21

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.

GuerillaNerd
  • 1,130
  • 1
  • 10
  • 12

2 Answers2

20

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
3

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

Artyom Emelyanenko
  • 1,323
  • 1
  • 11
  • 16
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197