Can't remove child in JPA using remove() method
I've done considerable research it doesn't work for me for some reason I
don't even get into the situation where I get "zombie" instances(like
existing in session but not in db anymore - I wish I had this situation)
since remove() is not propagated into database. The child record continues
to exist inside my db.
Consider two tables: User and Token(FK_User_Id) , relationship one-to-many
respectively
Inside DAO final code which doesn't work:
public void deleteToken(Token t) {
Token b = em.merge(t);
em.remove(b); // does nothing
em.flush();
}
Inside controller:
Object obj;
Token token;
obj = tokenService.getByString(urlToken); // query returning detached
object
User user;
if (obj != null) {
token = (Token) obj; // Detached, query is "fetch" overriding lazy
init, so token contains its user parent
user = token.getUser(); // simply get the user to which this token
belongs
if ((token.getExpiryDate().compareTo(new GregorianCalendar()
.getTime())) == 1) {
userService.activateUser(user); // user gets merged inside and
its relevant property is changed and propagated to db
successfully
tokenService.deleteToken(token); // this line calls DAO method
described in snippet above - it fails to delete the token, but
no error or exception - record simply stays in database
model.addAttribute("activationSuccess", "true");
}...
User entity:
public class User {
public static final String FIND_USER_BY_TOKEN = "findUserByToken";
public static final String FIND_USER_BY_USERNAME = "findUserByUsername";
public static final String FIND_USER_BY_EMAIL = "findUserByEmail";
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch =
FetchType.LAZY, orphanRemoval=true)
private List<Token> tokens = new ArrayList(); ...
Token entity:
@Entity
@Table(name = "token")
@NamedQueries({
@NamedQuery(name=Token.FIND_TOKEN_BY_STRING, query="Select t From
Token T where t.tokenString=:string")
})
public class Token {
public static final String FIND_TOKEN_BY_STRING = "findTokenById";
@Id
@GeneratedValue
Long id;
@ManyToOne(optional=true)
private User user; ...
Now if I call something like:
User c = b.getUser();
em.remove(c);
Inside DAO snippet, it deletes both token and user which is not what I
want. Only token must be deleted.
Basically what I am trying to do is to retrieve T(token) by string
property and along with it the user which owns this token. Then I retrieve
this user from token and change some property. All successful so far. Then
I want to delete the token as a final operation but in a way that user
will not be deleted.
I am on my fifth hour on this please help... I managed to setId to null
for the token, but it only gets me the point where token no longer has
owner but still persists in database. To delete it I tried to merge the
Token inside DAO with null which through me exception. Then I tried to set
Tokens list value to null inside User(which was retrieved from this token)
and it also through me exception.
How I am supposed to delete child entity which I retrieved with its parent
but keep parent present in db?
Thanks,
No comments:
Post a Comment