1.0jpa 2.0_在JPA 2.1中使用@Convert正确完成映射枚举
1.0jpa 2.0
如果您曾經(jīng)在JPA中使用過Java枚舉,那么您肯定會意識到它們的局限性和陷阱。 使用enum作為@Entity的屬性通常是一個很好的選擇,但是2.1之前的JPA不能很好地處理它們。 它給了您2 + 1個選擇:
托肖夫達(dá)林
幸運的是,幾天前發(fā)布的Java Persistence API 2.1 ( JSR-388 )提供了可插拔數(shù)據(jù)轉(zhuǎn)換器的標(biāo)準(zhǔn)化機制。 這樣的API以專有形式存在很久了,它并不是真正的火箭科學(xué),但是將其作為JPA的一部分是一個很大的改進。 據(jù)我所知, Eclipselink是迄今為止唯一可用的JPA 2.1實現(xiàn),因此我們將使用它進行一些實驗。
我們將從作為“ 窮人的CRUD:jqGrid,REST,AJAX和Spring MVC集成在房子里 ”的一部分開發(fā)的示例Spring應(yīng)用程序開始。 該版本沒有持久性,因此我們將在由Eclipselink支持的Spring Data JPA之上添加薄DAO層。 到目前為止,只有實體是Book :
@Entity public class Book {@Id@GeneratedValue(strategy = IDENTITY)private Integer id;//...private Cover cover;//... }其中Cover是enum :
public enum Cover {PAPERBACK, HARDCOVER, DUST_JACKET}ORDINAL和STRING都不是一個很好的選擇。 前者因為以任何方式重新排列前三個值都會破壞現(xiàn)有記錄的加載。 后者太冗長。 這是JPA中的自定義轉(zhuǎn)換器起作用的地方:
import javax.persistence.AttributeConverter; import javax.persistence.Converter;@Converter public class CoverConverter implements AttributeConverter<Cover, String> {@Overridepublic String convertToDatabaseColumn(Cover attribute) {switch (attribute) {case DUST_JACKET:return "D";case HARDCOVER:return "H";case PAPERBACK:return "P";default:throw new IllegalArgumentException("Unknown" + attribute);}}@Overridepublic Cover convertToEntityAttribute(String dbData) {switch (dbData) {case "D":return DUST_JACKET;case "H":return HARDCOVER;case "P":return PAPERBACK;default:throw new IllegalArgumentException("Unknown" + dbData);}} }好吧,親愛的讀者,我不會侮辱您,對此進行解釋。 將枚舉轉(zhuǎn)換為將存儲在關(guān)系數(shù)據(jù)庫中的任何內(nèi)容,反之亦然。 從理論上講,如果使用以下聲明,JPA提供程序應(yīng)自動應(yīng)用轉(zhuǎn)換器:
@Converter(autoApply = true它對我不起作用。 此外,在@Entity類中顯式聲明它們而不是@Enumerated也不起作用:
import javax.persistence.Convert;//...@Convert(converter = CoverConverter.class) private Cover cover;導(dǎo)致異常:
Exception Description: The converter class [com.blogspot.nurkiewicz.CoverConverter] specified on the mapping attribute [cover] from the class [com.blogspot.nurkiewicz.Book] was not found. Please ensure the converter class name is correct and exists with the persistence unit definition.錯誤或功能,我不得不在orm.xml提到轉(zhuǎn)換器:
<?xml version="1.0"?> <entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" version="2.1"><converter class="com.blogspot.nurkiewicz.CoverConverter"/> </entity-mappings>它飛! 我可以自由修改我的Cover枚舉(添加,重新排列,重命名),而不會影響現(xiàn)有記錄。
我想與您分享的一個技巧與可維護性有關(guān)。 每次您有一段從或到enum的代碼映射時,請確保已對其進行了正確的測試。 我并不是說要手動測試每個可能的現(xiàn)有值。 為了確保新的enum值在映射代碼中得到反映,我進行了更多測試。 提示:如果您添加新的enum值,但是忘記從中添加映射代碼,則下面的代碼將失敗(通過拋出IllegalArgumentException ):
for (Cover cover : Cover.values()) {new CoverConverter().convertToDatabaseColumn(cover); }JPA 2.1中的自定義轉(zhuǎn)換器比我們所看到的有用得多。 如果將JPA與Scala結(jié)合使用,則可以使用@Converter將數(shù)據(jù)庫列直接映射到scala.math.BigDecimal , scala.Option或小寫類。 在Java中,最終將有一種可移植的方式來映射Joda時間 。 最后但并非最不重要的一點是,如果您喜歡(非常)強類型的域,則可能希望擁有PhoneNumber類(帶有isInternational() , getCountryCode()和自定義驗證邏輯),而不是String或long 。 JPA 2.1中的這一小增加肯定會顯著提高域?qū)ο蟮馁|(zhì)量。
如果您想使用此功能, 可以在GitHub上找到示例Spring Web應(yīng)用程序。
翻譯自: https://www.javacodegeeks.com/2013/06/mapping-enums-done-right-with-convert-in-jpa-2-1.html
1.0jpa 2.0
總結(jié)
以上是生活随笔為你收集整理的1.0jpa 2.0_在JPA 2.1中使用@Convert正确完成映射枚举的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络用语nc粉是什么意思 来源是什么
- 下一篇: 百花丛中过片叶不沾身什么意思 百花丛中过