Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate persist entity without fetching association object. just by id

Tags:

java

hibernate

I have an simple association between 2 entities:

public class Car {      ...      @ManyToOne(fetch = FetchType.LAZY)     @JoinColumn(name = "user_id")     private User user;      ...  } 

and

public class User {      @Id     @GeneratedValue     @Column(name = "user_id")     private long userId;      ...      @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")     private Set<Car> cars;      ...  } 

Then I get some user id from client. For example, userId == 5;
To save car with user I need to do next:

User user = ... .findOne(userId);   Car car = new Car(); car.setUser(user); ... .save(car); 

My question is:
Can I persist car record without fetching user?

Similarly like I would do by using native SQL query: just insert userId like string(long) in Car table.

With 2nd lvl cache it will be faster but in my opinion I don't need to do extra movements.

The main reason that I don't want to use native Query is because I have much more difficult associations in my project and I need to .save(car) multiple times. Also i don't want to manually control order of query executions.

If I use session.createSQLQuery("insert into .....values()") will the Hibernate's batch insert work fine?



Correct me if I'm wrong.

Thanks in advance!

UPDATE:

Actually the mapping is similar to:

There is @ManyToMany association between User and Car. But cross table is also an entity which is named, for example, Passanger. So the mapping is next:

public class User{     @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", targetEntity = Passenger.class)     private Set<Passenger> passengers; } 

Cross entity

@IdClass(value = PassengerPK.class) public class Passenger {      @Id     @ManyToOne(fetch = FetchType.LAZY)     @JoinColumn(name = "user_id")     private User user;      @Id     @ManyToOne(fetch = FetchType.LAZY)     @JoinColumn(name = "car_id")     private Car car;      ... other fields ...  } 

Car entity:

public class Car {     @OneToMany(fetch = FetchType.LAZY, mappedBy = "car", targetEntity = Passenger.class, cascade = CascadeType.ALL)     private Set<Passenger> passengers; } 

And the code:

List<User> users = ... .findInUserIds(userIds); // find user records where userId is IN userIds - collection with user Ids Car car = new Car();       //initialization of car's fields is omitted if (users != null) {     car.setPassengers(new HashSet<>(users.size()));     users.forEach((user) -> car.getPassengers().add(new Passenger(user, car))); } ... .save(car); 
like image 677
InsFi Avatar asked Aug 10 '15 21:08

InsFi


People also ask

What is difference between persist and merge in Hibernate?

Persist should be called only on new entities, while merge is meant to reattach detached entities. If you're using the assigned generator, using merge instead of persist can cause a redundant SQL statement.

Is @entity annotation mandatory in Hibernate?

The entity class must be annotated with the Entity annotation or denoted in the XML descriptor as an entity. So, if you use annotations for mappings, @Entity is mandated by the specification and Hibernate has to adhere to it.

What is persistent entity in Hibernate?

A persistent entity represents one row of the database and is always associated with some unique hibernate session. Changes to persistent objects are tracked by hibernate and are saved into the database when commit calls happen.


1 Answers

"Can I persist car record without fetching user?"

Yes, that's one of the good sides of Hibernate proxies:

User user = entityManager.getReference(User.class, userId); // session.load() for native Session API   Car car = new Car(); car.setUser(user); 

The key point here is to use EntityManager.getReference:

Get an instance, whose state may be lazily fetched.

Hibernate will just create the proxy based on the provided id, without fetching the entity from the database.

"If I use session.createSQLQuery("insert into .....values()") will the Hibernate's batch insert work fine?"

No, it will not. Queries are executed immediately.

like image 50
Dragan Bozanovic Avatar answered Sep 26 '22 03:09

Dragan Bozanovic