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 Token by string property and along with it the user parent which owns this token. Then I retrieve this user from token and change some property for the user(changes propagated into db). 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(propagated into db), 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 threw 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 token entity which I retrieved with its parent but keep parent present in db?
SQL Hibernate log shows no delete query...after passing remove method.
Thanks,