1.0jpa 2.0_在JPA 2.1中使用@Convert正确完成映射枚举
1.0jpa 2.0
如果您曾經(jīng)在JPA中使用過(guò)Java枚舉,那么您肯定會(huì)意識(shí)到它們的局限性和陷阱。 使用enum作為@Entity的屬性通常是一個(gè)很好的選擇,但是2.1之前的JPA不能很好地處理它們。 它給了您2 + 1個(gè)選擇:
托肖夫達(dá)林
幸運(yùn)的是,幾天前發(fā)布的Java Persistence API 2.1 ( JSR-388 )提供了可插拔數(shù)據(jù)轉(zhuǎn)換器的標(biāo)準(zhǔn)化機(jī)制。 這樣的API以專有形式存在很久了,它并不是真正的火箭科學(xué),但是將其作為JPA的一部分是一個(gè)很大的改進(jìn)。 據(jù)我所知, Eclipselink是迄今為止唯一可用的JPA 2.1實(shí)現(xiàn),因此我們將使用它進(jìn)行一些實(shí)驗(yàn)。
我們將從作為“ 窮人的CRUD:jqGrid,REST,AJAX和Spring MVC集成在房子里 ”的一部分開(kāi)發(fā)的示例Spring應(yīng)用程序開(kāi)始。 該版本沒(méi)有持久性,因此我們將在由Eclipselink支持的Spring Data JPA之上添加薄DAO層。 到目前為止,只有實(shí)體是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都不是一個(gè)很好的選擇。 前者因?yàn)橐匀魏畏绞街匦屡帕星叭齻€(gè)值都會(huì)破壞現(xiàn)有記錄的加載。 后者太冗長(zhǎng)。 這是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);}} }好吧,親愛(ài)的讀者,我不會(huì)侮辱您,對(duì)此進(jìn)行解釋。 將枚舉轉(zhuǎn)換為將存儲(chǔ)在關(guān)系數(shù)據(jù)庫(kù)中的任何內(nèi)容,反之亦然。 從理論上講,如果使用以下聲明,JPA提供程序應(yīng)自動(dòng)應(yīng)用轉(zhuǎn)換器:
@Converter(autoApply = true它對(duì)我不起作用。 此外,在@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.錯(cuò)誤或功能,我不得不在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枚舉(添加,重新排列,重命名),而不會(huì)影響現(xiàn)有記錄。
我想與您分享的一個(gè)技巧與可維護(hù)性有關(guān)。 每次您有一段從或到enum的代碼映射時(shí),請(qǐng)確保已對(duì)其進(jìn)行了正確的測(cè)試。 我并不是說(shuō)要手動(dòng)測(cè)試每個(gè)可能的現(xiàn)有值。 為了確保新的enum值在映射代碼中得到反映,我進(jìn)行了更多測(cè)試。 提示:如果您添加新的enum值,但是忘記從中添加映射代碼,則下面的代碼將失敗(通過(guò)拋出IllegalArgumentException ):
for (Cover cover : Cover.values()) {new CoverConverter().convertToDatabaseColumn(cover); }JPA 2.1中的自定義轉(zhuǎn)換器比我們所看到的有用得多。 如果將JPA與Scala結(jié)合使用,則可以使用@Converter將數(shù)據(jù)庫(kù)列直接映射到scala.math.BigDecimal , scala.Option或小寫(xiě)類。 在Java中,最終將有一種可移植的方式來(lái)映射Joda時(shí)間 。 最后但并非最不重要的一點(diǎn)是,如果您喜歡(非常)強(qiáng)類型的域,則可能希望擁有PhoneNumber類(帶有isInternational() , getCountryCode()和自定義驗(yàn)證邏輯),而不是String或long 。 JPA 2.1中的這一小增加肯定會(huì)顯著提高域?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正确完成映射枚举的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网络用语nc粉是什么意思 来源是什么
- 下一篇: 百花丛中过片叶不沾身什么意思 百花丛中过