【问题标题】:JPA/Hibernate OneToOne association, persist call inserts entity with null IdJPA/Hibernate OneToOne 关联,持久调用插入具有空 Id 的实体
【发布时间】:2012-11-02 13:59:40
【问题描述】:

我的实体如下:

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

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

    [...]
}

抽象的Survey上面可以有两种具体的类:

@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(UserSurvey 和 SupervisorSurvey 的外部 ID 列值不为空),但插入 UserSurvey 和 SupervisorSurvey 时使用 NULL ID。

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

【问题讨论】:

  • 希望对您有所帮助:stackoverflow.com/questions/9649515/…
  • @perissf 很遗憾没有;正如我在调试会话期间看到的那样,在 bean 中正确设置了 ID(我还可以看到 hibernate 执行 get_last_insert_id 查询)。但我得到一个空 ID 列值。 hibernate 没有在该表列上放置主键也很奇怪。

标签: java hibernate jpa one-to-one


【解决方案1】:

我放弃了 @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 的替代答案,因为问题集中在那个特定的注释上。

【讨论】:

    【解决方案2】:

    当我们使用实体调用 persist() 时,JPA 会为数据库创建一个新对象。当您将 @GeneratedValue(strategy=GenerationType.AUTO) 用于 id 时,JPA 将负责 id 生成。由于 JPA 在刷新时为关联实体生成 id,因此您需要刷新 entityManager 实例。

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

    刷新后,您将获得实体的 id。

    【讨论】:

      猜你喜欢
      • 2013-01-17
      • 2021-02-25
      • 1970-01-01
      • 2011-09-22
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2021-05-22
      • 2020-05-19
      相关资源
      最近更新 更多