Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

java - Always use primitive object wrappers for JPA @Id instead of primitive type?

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;
}

So, when I run:

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

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

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.

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

getId(entity) == null;

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...