总是对 JPA @Id 使用原始对象包装器而不是原始类型? [英] Always use primitive object wrappers for JPA @Id instead of primitive type?

查看:16
本文介绍了总是对 JPA @Id 使用原始对象包装器而不是原始类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现将原始类型用作 JPA 的对象 @Id 并结合 Spring Data JPA 存在问题.我在父端与Cascade.ALL有父子关系,子有PK,同时也是父的FK.

I've found the issue with using primitive type as an object @Id for JPA in conjunction with Spring Data JPA. I have parent/child relationship with Cascade.ALL on the parent side, and child has PK which at the same time is also parent's FK.

class Parent {
    @Id
    private long id;

    @OneToOne(mappedBy = "parent", cascade = ALL)
    private Child child;
}

class Child {
    @Id
    @OneToOne
    private Parent parent;
}

所以,当我跑步时:

...
Parent parent = new Parent();
Child child  = new Child(parent);
parent.setChild(child);  
em.persist(parent)
...

一切正常.但是我使用 Spring Data JPA 来持久化实体,所以我改为运行:

everything works fine. But I used Spring Data JPA to persist the entity, so I run instead:

parentRepository.save(parent); // instead of em.persist(parent);

这个失败了,但有以下异常:

and this one was failed with the following exception:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Parent

问题是 Spring Data JPA save() 方法检查实体是否是新的,如果是新的,则使用 em.persist() 否则 使用 em>em.merge().

The problem was that Spring Data JPA save() method checks whether the entity is new, and if it is new then em.persist() is used otherwise em.merge() is used.

这里有趣的部分是 Spring 如何检查实体是否是新的:

The interesting part here how Spring checks whether the entity is new or not:

getId(entity) == null;

当然,这是错误的,因为我使用 long 作为 @Id 的类型,而 long 的默认值是 0.当我将 long 更改为 Long 时,一切都适用于 Spring Data JPA.

And, of course, this was false, because I used long as the type for @Id, and the default value for long is 0. When I changed long to Long everything works with Spring Data JPA also.

因此,建议的做法是始终为原始类型(如 Long 而不是 long)而不是原始类型使用对象包装器.任何将此描述为推荐做法的第 3 方资源都会非常好.

So is it the recommended practice always to use object wrappers for the primitive types (like Long instead of long) instead of primitive types. Any 3rd party resource describing this as the recommended practice would be very nice.

推荐答案

我会说是的,因为您所看到的情况,建议使用对象类型而不是基元.无法通过原始标识符区分实体是新的还是预先存在的.我已经使用 hibernate 多年了,我总是使用对象作为标识符.

I would say yes it is recommended to use object types instead of primitives because of the case you are seeing. There is no way of distinguishing if the entity is new or pre existing with a primitive identifier. I have used hibernate for years and I always use objects for identifiers.

这篇关于总是对 JPA @Id 使用原始对象包装器而不是原始类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆