JPA / Hibernate OneToOne关联,持久化调用插入具有null Id的实体

时间:2012-11-14 03:32:53

标签: java hibernate jpa one-to-one

我的实体如下:

@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 ID。

为什么会这样? 如果我在persist方法之后调试代码,我可以检查对象实例的ID,结果实际填充它们。

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

我放弃了@OneToOne并将其转换为@ManyToOneunique=true约束@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的替代答案,因为问题集中在那个特定的注释上。