Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

saving entity with referenced dependent entities using hibernate

Tags:

java

hibernate

We are using Hibernate as persistency layer and have complex object model. Without exposing the real data model I want to explain the problem using the following simple example.

class Person {
    private Integer id; //PK
    private String name;
    private Account account;
    // other data, setters, getters
}


class Account {
    private Integer id; //PK
    // other data, setters, getters
}

The DB mapping is defined using HBM as following:

 <class name="Person" table="PERSON">
    <id name="id" column="ID">
        <generator class="native"/>
    </id>
    <version name="version" type="java.lang.Long"/>
    <property name="name" type="java.lang.String" length="50" column="NAME"/>
    <many-to-one name="account" column="ACCOUNT_ID"
                class="com.mycompany.model.Account"/>

</class>

I have to save new populated instance of Person linked to existing Account. The call is originated by web client, so at my layer I get instance of Person referenced to instance of Account that holds its ID only.

If I try to call saveOrUpdate(person) the following exception is thrown:

org.hibernate.TransientObjectException: 
object references an unsaved transient instance - save the transient instance before flushing: 
com.mycompany.model.Account

To avoid this I have to find the persisted object of Account by ID and then call person.setAccount(persistedAccount). In this case everything works fine.

But in real life I deal with dozens of entities referenced to each other. I do not want to write special code for each reference.

I wonder whether there is some kind of generic solution for this problem.

like image 775
AlexR Avatar asked Jan 12 '12 17:01

AlexR


People also ask

What is the use of @entity annotation in Hibernate?

@Entity annotation marks this class as an entity. @Table annotation specifies the table name where data of this entity is to be persisted. If you don't use @Table annotation, hibernate will use the class name as the table name by default. @Id annotation marks the identifier for this entity.

How does saveOrUpdate work in Hibernate?

When you use . saveOrUpdate() Hibernate will check if the object is transient (it has no identifier property) and if so it will make it persistent by generating it the identifier and assigning it to session. If the object has an identifier already it will perform .

What is @ID in Hibernate?

The most straightforward way to define an identifier is by using the @Id annotation. Simple ids are mapped using @Id to a single property of one of these types: Java primitive and primitive wrapper types, String, Date, BigDecimal and BigInteger.


1 Answers

To persist one entity, you just need to have the references to its direct dependencies. The fact that these other entities reference other entities doesn't matter.

The best way to do it is to get a proxy to the referenced entity, without even hitting the database, using session.load(Account.class, accountId).

What you're doing is the right thing to do: get a reference to the persistent account, and set this reference into the newly created account.

like image 109
JB Nizet Avatar answered Sep 19 '22 14:09

JB Nizet