How to create a child of an existing super object using JOINED and Hibernate inheritance strategy

How can I create a child with a saved super object with Hibernate?

Consider the following example: User with identifier 1, firstName Kevin and laseName Smith is stored in the database. By the time of the database model, the new Entity Auditor , which is a child of the User class, has been expanded. The JOINED strategy is used for JOINED , so the database model now has tow tables: user and auditor. These tables are combined using user_id FK.

I would like to create an Auditor object of type Kevin Smith and save it. The problem is that the operations are transactional and Hibernate throws a NonUniqueObjectException . Is there any way how to safely discard an object with a stored object than a child? I tried to fetch the given User object, but still the same.

Custom object

 @Entity @Table(name = "user") @Inheritance(strategy = InheritanceType.JOINED) public class User{ private Long id; private String firstName; private String lastName; // getters and setters } 

Auditor

 @Entity @Table(name = "auditor") public class Auditor extends User { // some properties } 

Logics

 public void createAuditorOfUser(final long userId) { final User user = userService.getUserById(userId); // ... final Auditor auditor = new Auditor(); auditor.setId(user.getId()); auditor.setFirstName(user.getFirstName()); auditor.setLastName(user.getLastName()); userService.evict(user); // will throw NonUniqueObjectException auditorService.update(auditor); // ... } 

I hope the problem is clear, if not, I will try to improve the description.

+5
source share
2 answers

I think Hibernate intentionally limits this behavior. Of course, you can do this with your own SQL workaround (as you already did).

In Java, we also cannot drop a superclass object to a subclass, and then fill in new fields of the same object. Instead, create a new instance of the subclass, then copy the fields.

The one-to-one relationship seems to be better suited to the required functions.

+1
source

I think the problem is that you want to create the user as a role, and the user is not a role, I think he is more suitable to say that the auditor is a role (inheritance) and the User has a role (composition), therefore maybe you need to have common user properties in one object, and the role table where you need to abstract your inheritance

Something like that

 @Entity @Table(name = "user") public class User{ //user properties //Here is where you will share the user @optional = false, cascade = CascadeType.ALL, mappedBy = "user" private Role role // getters and setters } 

And here your entity role with will be the parent class

 @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Role implements Serializable { @SequenceGenerator(name = "ROLE_SEQ", sequenceName = "ROLE_SEQ", allocationSize = 1) @GeneratedValue(generator = "ROLE_SEQ") @Id private Long idRole; @OneToOne(optional = false) private User user; //getter and setters 

}

and your specific role

 @Entity @Table(name = "auditor") public class Auditor extends Role { // some properties } 

So you can do something like this in java

  User user = new User(); //set all the properties that you need for user or the reference for an existing user . . //Set the role that you need Auditor auditor = new Auditor(); auditor.setUser(user); user.setRole(auditor); userDAO.insert(user); 
0
source

Source: https://habr.com/ru/post/1203396/


All Articles