Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I save an entity with foreign key without loading the related entity in JPA?

Tags:

java

orm

jpa

I have two entities:

Account {
  @Id
  Long id;
}

Preference {
  ...
  @ManyToOne
  private Account account;
}

When saving a Preference, I have the accountId, but I don't have an Account entity. How should I save the preference in this situation?

Load the Account entity and set it on the preference? To me, that seems like an erroneous trip to the database.

Have an accountId field that is persistable and make the Account field read-only? Having both an accountId field and an Account field seems redundant?

Use a NamedQuery to persist the Preference? I was hoping to just generically save an entity without special logic for.

like image 269
GuerillaNerd Avatar asked Oct 10 '12 21:10

GuerillaNerd


People also ask

How do I persist foreign key in JPA?

Use the getReference call of the entityManager to load customer object using the id and then set that onto the customer history. In most cases this call would return a proxy with just the id embedded, the customer attributes will not be loaded unless some other method of the customer is invoked.

How can we declare entity without primary key in JPA?

Sometimes your object or table has no primary key. The best solution in this case is normally to add a generated id to the object and table. If you do not have this option, sometimes there is a column or set of columns in the table that make up a unique value. You can use this unique set of columns as your id in JPA.

How do you save a list of entities in Spring data JPA?

For SpringData Jpa, a cleaner approach will be to use repository. saveAll instead of a for loop with repository. save . saveAll will automatically iterate through the list and save it.


2 Answers

Use em.getReference(Account.class, accountId). It returns an uninitialized proxy on the entity, without going to the database. Your use-case is the main reason for the existence of this method.

like image 102
JB Nizet Avatar answered Oct 21 '22 07:10

JB Nizet


Additional to em.getReference or JpaRepository.getOne manipulation for spring-data-jpa there are other solutions:

  1. It is possible via Update Query. E.g. with spring-data

    @Transactional
    @Modifying
    @Query("UPDATE Preference SET prop1=:prop1 .. WHERE u.id=:id")
    int updatePreference(@Param("id") int id, @Param("prop1") String prop1, ...);
    

see Updating Entities with Update Query in Spring Data JPA

  1. There is spring-data DomainClassConverter that is auto resolving entity instances from request parameters or path variables. E.g.

    @GetMapping("/employees/{id}")
    public Employee getEmployeeById(@PathVariable("id") Employee employee) {
        return employee;
    } 
    

See Resolving entity instances from request parameters or path variables

like image 3
Grigory Kislin Avatar answered Oct 21 '22 08:10

Grigory Kislin