休眠零对一

发布于 2024-09-14 08:51:14 字数 1508 浏览 6 评论 0原文

我正在尝试在两个实体之间建立零对一的关系。也就是说,父实体可以在没有关联子实体的情况下保存,也可以与关联子实体一起保存。 以下是 2 个实体类...


Employee (Parent)

public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="EMP_NAME")
    private String name;

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = {CascadeType.ALL})
    private EmployeeInfo info;

    @Column(name="EMP_ENUM")
    private Integer enumId;

EmployeeInfo (Child)

public class EmployeeInfo {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;

        @Column(name="EMPLOYEE_EMAIL")
        private String email;

具有唯一 Parent (Employee) 的这种关系和 id 列表在 MySql DB 中设置为自动增量,问题是在保存父级->子对象图时,出现以下异常

org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [insert into EMP_INFO 
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value

我尝试在数据库中将子表的 Id 属性设置为自动增量 ,这样一个Parent->Child对象图的持久化就成功了。 但是,此处描述的问题浮出水面,因为我有一个场景我想在没有关联的 EmpInfo 对象的情况下保存父(Employee)对象,因此因此不希望在 Child 的 id 列上具有自动增量


一种解决方案可能是不使用 PrimaryKeyJoinColumn,而是使用特定的 JoinColumn,但这会向我现有的表添加不必要的列。


有人遇到过这样的问题吗?如果是的话,任何指示都会很有帮助。

I am trying to establish a relationship between 2 entities which would be zero-to-one. That is, the Parent can be saved without the associated Child entity and also along with the assoicated Child.
Following are the 2 Entity classes...


Employee (Parent)

public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="EMP_NAME")
    private String name;

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = {CascadeType.ALL})
    private EmployeeInfo info;

    @Column(name="EMP_ENUM")
    private Integer enumId;

EmployeeInfo (Child)

public class EmployeeInfo {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;

        @Column(name="EMPLOYEE_EMAIL")
        private String email;

With such kind of a relation and id column of the only Parent (Employee) table set to AUTO INCREMENT in MySql DB, the problem is that while saving a Parent->Child object graph, I get the following exception

org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [insert into EMP_INFO 
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value

I tried setting the Child Table's Id property to AUTO INCREMENT in the DB , and the persistence of such a Parent->Child object graph is successful.
However, the problem described here surfaces, because I have a scenario in which I would like to save the parent (Employee) object without the associated EmpInfo object, and hence do NOT want to have AUTO INCREMENT on the Child's id column.


One solution could be not use the PrimaryKeyJoinColumn, but use a particular JoinColumn, but that adds an unnecessary column to my existing Table.


Has anyone come across such a problem? If yes, any pointers would be much helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尐偏执 2024-09-21 08:51:14

最后,感谢 Pascal 和我这边的一些谷歌搜索,我让它工作了。显然,我无法将本机密钥生成器用于父级可以在没有子级的情况下存在的关系(可选= true)。
最终起作用的事情如下,给我留下了必须处理 Hibernate 特定注释(@GenericGenerator)的缺点,并且还必须使用双向关系而不是我想要的单向关系。

Employee (Parent) class remains unchanged as above. It has AUTO INCREMENT on the Id column.

至于子类(EmployeeInfo),它更改为以下内容,并且再次没有在 Id 列上设置自动增量。

@Table(name="EMP_INFO")
@Entity
public class EmployeeInfo {
    @Id
    @GeneratedValue(generator="foreign")
    @GenericGenerator(name="foreign", strategy = "foreign", parameters={
    @Parameter(name="property", value="verifInfo")}) 
    private Long id;

    @OneToOne(optional=false)
    @JoinColumn (name="id")
    private Employee emp;

    @Column(name="EMPLOYEE_EMAIL")
    private String email;

这帮助我实现了我想要的,但缺点是,GenericGenerator 不是 JPA 注释,它是 hibernate 注释,遗憾的是我现在只能用它,因为 JPA 目前不支持此(或任何类似)注释。

无论如何,它有助于解决此类情况:-)

Finally, I got it working thanks to Pascal and some googling from my side. Apparently, I cannot use the Native key generator for such relationships where the parent can exist without the child (optional = true).
The thing that worked finally was the following, leaving me the downside of having to deal with Hibernate specific annotation (@GenericGenerator) and also having to make-do with bi-directional relationships instead of the unidirectional that I wanted.

Employee (Parent) class remains unchanged as above. It has AUTO INCREMENT on the Id column.

As for the child class (EmployeeInfo) it changed to the following, and again WITHOUT having the AUTO INCREMENT set on the Id column.

@Table(name="EMP_INFO")
@Entity
public class EmployeeInfo {
    @Id
    @GeneratedValue(generator="foreign")
    @GenericGenerator(name="foreign", strategy = "foreign", parameters={
    @Parameter(name="property", value="verifInfo")}) 
    private Long id;

    @OneToOne(optional=false)
    @JoinColumn (name="id")
    private Employee emp;

    @Column(name="EMPLOYEE_EMAIL")
    private String email;

This helped me achieve what I wanted but on the downside, GenericGenerator is not a JPA annotation, it is a hibernate annotation, and sadly I have to make do with that as of now because JPA does not currently support this(or any similar) annotation.

Anyway, it helps to get through such cases :-)

2024-09-21 08:51:14

我有一个场景,我想在没有关联的 EmpInfo 对象的情况下保存父(Employee)对象。

默认情况下,OneToOne可选 属性为 true,这正是您想要的。

但是,您在此处以某种方式滥用了 @PrimaryKeyJoinColumn (嗯,这实际上取决于您真正想要实现的目标,但您当前的注释组合不正确)。

如果您想要映射OneToOne具有共享主键,请使用@PrimaryKeyJoinColumn。但在这种情况下,不要在 EmployeeInfo 上使用 GenelatedValue 并手动设置 id,或者,如果您不想手动设置它,请使用 Hibernate 特定 外国生成器,我已经在您之前的问题。另请检查下面提到的相关问题。

并且如果您不想使用共享主键(就像在当前代码中一样,因为您试图获取数据库生成的ID),那么不要使用 PrimaryKeyJoinColumn

你必须做出选择。

参考

  • JPA 1.0规范:
    • 9.1.32 PrimaryKeyJoinColumn 注解

相关问题

I have a scenario in which I would like to save the parent (Employee) object without the associated EmpInfo object.

The optional attribute of a OneToOne is true by default, which is what you want.

However, you are somehow misusing the @PrimaryKeyJoinColumn here (well, it actually depends on what you really want to achieve but your current combination of annotations is not correct).

IF you want to map a OneToOne with a shared primary-key, use the @PrimaryKeyJoinColumn. But in that case, don't use a GeneratedValue on EmployeeInfo and set the id manually or, if you don't want to set it manually, use the Hibernate specific foreign generator that I already mentioned in your previous question. Check also the related question mentioned below.

And IF you do not want to use a shared primary key (like in your current code since you're trying to get the id generated by the database), then do not use the PrimaryKeyJoinColumn.

You have to make a choice.

References

  • JPA 1.0 specification:
    • 9.1.32 PrimaryKeyJoinColumn Annotation

Related question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文