Reputation: 861
I'm using Spring Data and i have such class structure:
A has-a B and B has-a List<C>
and code:
List<A> aList= aRepository.findAll();
aList.forEach(a-> a.getB().setC(null));
I don't need List of C's in frontend (in this particular scenario). But when I set C as null, the EntityManager
is not in detached state and it sets C
as null
in the database. How to detach entities in a List
after I retrieve them? I tried this:
EntityManager em=entityManagerFactory.createEntityManager();
aList.forEach(a -> em.detach(a) ......);
But it didn't work. Any suggestions?
EDIT:
Here's the actual entities (without unnecessary fields):
Session
(Class A in above example):
@Entity
public class AuthSession {
private AuthUser user;
@ManyToOne
@JoinColumn(name = "user_id",foreignKey = @ForeignKey(name = "fk_auth_user_id"))
public AuthUser getUser() {
return user;
}
public void setUser(AuthUser user) {
this.user = user;
}
}
User
(class B in above example):
@Entity
public class AuthUser {
private Set<AuthRole> roles;
@ManyToMany
@JoinTable(
name = "USER_ROLE_LINK",
schema = "iapauth",
joinColumns = @JoinColumn(name = "user_id"),
foreignKey = @ForeignKey(name = "fk_user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"),
inverseForeignKey = @ForeignKey(name = "fk_role_fk"))
public Set<AuthRole> getRoles() {
return roles;
}
public void setRoles(Set<AuthRole> roles) {
this.roles = roles;
}
Role
(Class C in above example):
@Entity
public class AuthRole{}
I have a code to add roles to user (new entries in auto-generated link-table "USER_ROLE_LINK"). It works fine. And i have this code to retrieve all sessions:
EntityManager em=entityManagerFactory.createEntityManager();
List<AuthSession> sessions=sessionRepo.findAll();
sessions.forEach(x->{
em.detach(x);
AuthUser user=x.getUser();
if(user!=null) user.setRoles(null);
});
return sessions;
But after this code executes, entries in user-role
table (those whose users are in current session) are deleted.
Upvotes: 0
Views: 5944
Reputation: 81862
While the idea of detaching is a correct one, you are detaching the wrong entities.
With this code
List<AuthSession> sessions=sessionRepo.findAll();
sessions.forEach(x->{
em.detach(x);
AuthUser user=x.getUser();
if(user!=null) user.setRoles(null);
});
All the AuthUser
s referenced by the AuthSession
are still managed by the EntityManager
(i.e. not detached). You need to either explicitly detach them or add a cascade configuration to AuthSession.user
See: https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html
Also as Mukhamedali Zhadigerov describes in the comments one should use an injected EntityManager
.
Upvotes: 2