2012-11-14 84 views
0

我的實體如下:JPA /休眠OneToOne協會,堅持用空ID呼叫插入實體

@Entity 
@Table(name="`surveys`") 
@Inheritance 
@DiscriminatorColumn(name="`type`") 
public abstract class Survey implements Serializable, Comparable<Survey> { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer id; 

    [...] 
} 

以上的抽象調查可以有兩種具體類:

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorValue(value="SV") 
public class SupervisorSurvey extends Survey implements Serializable { 

    @OneToOne(mappedBy="supervisorSurvey",cascade=CascadeType.ALL) 
    private SurveyPair surveyPair; 

    [...] 
} 

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorValue(value="US") 
public class UserSurvey extends Survey implements Serializable { 

    @OneToOne(mappedBy="userSurvey",cascade=CascadeType.ALL) 
    private SurveyPair surveyPair; 

    [...] 
} 

然後一個實例SurveyPair抓住兩種類型之一:

@Entity 
@Table(name="`surveypairs`") 
public class SurveyPair implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int id; 

    @OneToOne 
    @JoinColumn(name="`userSurveyId`",unique=true) 
    private UserSurvey userSurvey; 

    @OneToOne 
    @JoinColumn(name="`supervisorSurveyId`",unique=true) 
    private SupervisorSurvey supervisorSurvey; 
} 

現在的問題:我創建對象後柯此:

// survey pair 
SurveyPair surveyPair = new SurveyPair(reference); 

// user side 
UserSurvey usSurvey = new UserSurvey(user); 
usSurvey.setSurveyPair(surveyPair); 
surveyPair.setUserSurvey(usSurvey); 

// supervisor side 
SupervisorSurvey svSurvey = new SupervisorSurvey(Application.getLoggedUser(), user); 
svSurvey.setSurveyPair(surveyPair); 
surveyPair.setSupervisorSurvey(svSurvey); 

SurveyInput.getInstance().persist(surveyPair); 

上述呼叫堅持:

JPAHelper db = new JPAHelper(); 
EntityManager em = db.getEntityManager(); 
em.getTransaction().begin(); 
em.persist(surveyPair.getUserSurvey()); 
em.persist(surveyPair.getSupervisorSurvey()); 
em.persist(surveyPair); 
em.getTransaction().commit(); 
em.close(); 

正確地插入SurveyPair(外國的ID列值UserSurvey和SupervisorSurvey不爲空),但UserSurvey和SupervisorSurvey裝入了NULL標識。

爲什麼會發生這種情況? 如果我在persist方法之後調試代碼,我可以檢查對象實例的ID,並將其結果實際填充。

+0

希望這可以幫助:http://stackoverflow.com/questions/9649515/how-to-get-id-of-last-persisted-entity-using-jpa – perissf

+0

@perissf不幸的是;正如我在調試會話期間看到的那樣,這些ID在Bean中正確設置(我也可以看到hibernate正在執行get_last_insert_id查詢)。但是我得到一個空ID列值。這也是奇怪的,休眠沒有把主鍵放在該表列。 –

回答

0

我放棄了與@OneToOne並與unique=true一個@ManyToOne關係contrained @JoinColumn將它轉換:

@XmlElement(name="userSurvey") 
@ManyToOne(optional=false) 
@JoinColumn(name="`userSurveyId`",unique=true) 
private UserSurvey userSurvey; 

@XmlElement(name="supervisorSurvey") 
@ManyToOne(optional=false) 
@JoinColumn(name="`supervisorSurveyId`",unique=true) 
private SupervisorSurvey supervisorSurvey; 

它這樣工作;但如果有人提出這樣的解決方案,我會接受使用@OneToOne的替代答案,因爲問題集中在特定的註釋上。

1

當我們用實體調用persist()時,JPA爲數據庫創建一個新的對象。當您爲id使用@GeneratedValue(strategy = GenerationType.AUTO)時,JPA將負責生成id。由於JPA在刷新時爲關聯實體生成id,所以您需要刷新entityManager實例。

Entity entity = new Entity(); 
entity.setAddresse("Address"); 
em.persist(entity); 
em.flush(); 

刷新後你會得到你的實體ID。