0

Iam using Spring Hibernate with JPA. cascade=CascadeType.ALL and @Id @GeneratedValue(strategy = GenerationType.IDENTITY). I have two tables one is User the other is photos when I want to add a new photo do I need to go and take the User from the database and then set it as a user in the photo with photo.setUser(user). Is there a way to just do User user = new User(); user.setId(1) and then put it in the photo with photo.setUser() without a full reference I am getting detached entity passed to persist when I execute repo.save(photo) when I am setting only the id.

What I want to do is:

User user = new User();
user.setId(1);
photo.setUser(user);
repo.save(photo)

Where user is already created in the database and has several photos.

instead of:

User user = repo.findUserById(1);
photo.setUser(user);
repo.save(photo);

my entities:

@Entity
@Table(name = "users")
public class Photo implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @OneToMany(cascade = CascadeType.ALL,mappedBy = "user", fetch = FetchType.EAGER)
    private List<Photo> photos = new ArrayList<>();


@Entity
@Table(name = "photos")
public class Photo implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;
  • any specific reason why you don't want to find the user by id and set it in the photo? If you just want to store the user id in photo without fetching it, you can create a field in photo `userId` and make the `user` field read-only. See this [SO answer](https://stackoverflow.com/questions/30090941/jpa-readonly-mapping) – Mustafa Feb 16 '19 at 20:31
  • @Mustafa I mean its another transaction to the database and I can find a workaround to store the user, but I thought I could do this only by setting the primary key, without finding the user first. –  Feb 16 '19 at 20:48

1 Answers1

1

Use EntityManager.getReference() to get an user object. The nice things of it compared with EntityManager.find() is that it will not trigger additional SQL to get the user object.

The user object is just a proxy with only ID is set. Just make sure you do not access its properties other than ID before save , then no additional SQL will be triggered to get the user which is good for setting up the foreign key to the existing object with the known ID.

User  user = entityManager.getReference(1, User.class);
photo.setUser(user);
repo.save(photo)

If you are using spring-data repository , the equivalent method is getOne() which will internally call EntityManager.getReference()

Ken Chan
  • 84,777
  • 26
  • 143
  • 172