2014-11-25 71 views
2

大家好,JPA具有外鍵和枚舉的複合鍵

我試圖從遺留數據庫中構建所有jpa實體。我有一個反覆出現的問題:一些「主要」實體有一系列「翻譯」,其中主鍵是「主」+「語言」標識符的關鍵。語言存儲在數據庫和Enum上以簡化他們的處理。

的使用JPA執行即時通訊是休眠4.

以下,當前的實現:

主:(消息)

@Entity 
@Table(name="MESSAGES") 
@NamedQueries({ 
public class Message implements Serializable { 

    @Id 
    @SequenceGenerator(name="MESSAGES_MESSAGEID_GENERATOR", sequenceName="SEQ_MSG_messageID") 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MESSAGES_MESSAGEID_GENERATOR") 
    @Column(name="messageId") 
    private long id; 

    @OneToMany(mappedBy="message", fetch=FetchType.EAGER) 
    private Set<MessageDesc> descriptions; 
} 

翻譯:(MessageDesc)

@Entity 
@Table(name="MESSAGEDESCS") 
public class MessageDesc implements Serializable, Translatable { 

    @EmbeddedId 
    private MessageDescPK id; 

    @NotNull 
    @Enumerated(EnumType.ORDINAL) 
    @Column(name = "LANGUAGEID") 
    private LanguageEnum language; 

    @NotNull 
    @ManyToOne 
    @JoinColumn(name="MESSAGEID") 
    private Message message; 
} 

翻譯複合鍵:(MessageDescPK)

@Embeddable 
public class MessageDescPK implements Serializable { 

    @Column(name="messageid", nullable = false, insertable = false) 
    private long message; 

    @Column(name="languageid", nullable = false, insertable = false) 
    private int language; 
} 

語言:(LanguageEnum)

public enum LanguageEnum { 
    FRENCH(0, "FR"), 
    DUTCH(1, "NL"); 

    private int id; 
    private String desc; 
} 

的問題是,試圖堅持一些翻譯上的主(消息)的實體時,說明和那些設置了語言和信息的翻譯,我不斷收到以下例外:

org.springframework.orm.jpa.JpaSystemException: org.hibernate.id.IdentifierGenerationException: null id generated for:class something.persistence.entity.message.MessageDesc; nested exception is javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: null id generated for:class something.persistence.entity.message.MessageDesc 
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321) 
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403) 
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) 
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111) 

我不明白爲什麼PK在messageDesc實例上同時設置語言和消息(已保留)後爲空。任何幫助,評論,線索將不勝感激。

謝謝!

回答

1

這就是我們解決了這個問題:

MessageDesc

@NotNull  
@Enumerated(EnumType.ORDINAL) 
@Column(name = "LANGUAGEID", insertable=false, nullable = false) 
private LanguageEnum language; 

@NotNull  
@ManyToOne 
@JoinColumn(name="MESSAGEID", insertable=false, nullable = false) 
private Message message; 

@PrePersist 
private void prePersist(){ 
    if (getId() == null){ 
     MessageDescPK id = new MessageDescPK(); 
     //the way this enum is persisted is EnumType.ORDINAL 
     id.setLanguage(getLanguage().ordinal()); 
     id.setMessage(getMessage().getId()); 
     this.setId(id); 
    } 
} 

MessageDescPk

@Embeddable 
public class MessageDescPK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    @Column(name="messageid", nullable = false, insertable = false, updatable=false) 
    private long message; 

    @Column(name="languageid", nullable = false, insertable = false, updatable=false) 
    private int language; 

希望這有助於:)