user497087
user497087

Reputation: 1591

Cannot delete entity (JPA & Spring)

What ever I try, I cannot delete a user entity when I call delete() from my userService class. I get an exception java.lang.IllegalArgumentException: Entity must be managed to call remove: com.blackbox.genesis.entities.User@30168a, try merging the detached and try the remove again. I'm obviously doing something wrong - despite merging, but I can't see what. Everything else works fine - I can create and update user entities without any problem.

Regards

My entity class;

@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "EMAIL")})
public class User implements Serializable {


@Id
@Column(name="username", length=50)
private String username;
@OneToOne(cascade = {CascadeType.ALL})
private Password password;
private boolean enabled;
private int serial;
private String email;
@Version
private int version;

@ElementCollection(targetClass=Authority.class)
@CollectionTable(name="USER_AUTHORITY")
private List<Authority> authorities;

@OneToMany(mappedBy="user", fetch=FetchType.LAZY, cascade=CascadeType.ALL, ``orphanRemoval=true)
private Set<License> licenses;

private static final long serialVersionUID = 1L;

public User() {
    super();
    this.authorities = new ArrayList<Authority>();
} 
.... getters/setters.

My DAO class;

@Repository
public class UserJpaController {

@PersistenceContext
EntityManager em;

protected static final Logger logger =   Logger.getLogger("com.blackbox.genesisng.entities.UsersJpaController");

public void create(User user) throws PreexistingEntityException, Exception {



    if (findUser(user.getUsername()) != null) {
        throw new PreexistingEntityException("Users " + user + " already exists.");
    }

      em.persist(user);
      em.flush();


}

public void edit(User user) throws NonexistentEntityException, Exception {

        user = em.merge(user);
        em.flush();
}


public void destroy(String id) throws NonexistentEntityException {
        User user = em.find(User.class, id);
        user = em.merge(user);
        em.remove(user);


}

public List<User> findUserEntities() {
    return findUserEntities(true, -1, -1);
}

public List<User> findUserEntities(int maxResults, int firstResult) {
    return findUserEntities(false, maxResults, firstResult);
}

private List<User> findUserEntities(boolean all, int maxResults, int firstResult) {
        Query q = em.createQuery("select object(o) from User as o");
        if (!all) {
            q.setMaxResults(maxResults);
            q.setFirstResult(firstResult);
        }
        return q.getResultList();

}

public User findUser(String id) {
        return em.find(User.class, id);

}

public int getUserCount() {
        Query q = em.createQuery("select count(o) from User as o");
        return ((Long) q.getSingleResult()).intValue();

}

public User findUserByEmail(String email) {

        Query q = em.createQuery("select Object(o) from User as o where              o.email          =     :email");
        q.setParameter("email", email);
        List list = q.getResultList();
        if (list.size() == 0) {
            return null;
        }
        return (User) list.get(0);


}

public boolean exists(String id) {

    try {
         em.getReference(User.class,id);  
         return true;
         } 
         catch (EntityNotFoundException e) {
             return false;
         }


}



}

and finally, the relevant portion of my service class

@Service
public class UserService  {

@Autowired
UserJpaController dao;

@Autowired
LicenseJpaController licenseDao;

        @Transactional
public void delete(UserDTO userDTO) {
    if (exists(userDTO.getUserName())){
        try {
        dao.destroy(userDTO.getUserName());
        } catch (NonexistentEntityException e) {
            // ignore as the previous test should prevent this.
        }

    }

}

Upvotes: 0

Views: 4541

Answers (2)

user497087
user497087

Reputation: 1591

So sorry, but I'm an idiot! I was not calling the service class that I thought I was. Fixed that and everything works as expected. Once again, sorry folks.

Regards

Upvotes: 1

Ralph
Ralph

Reputation: 120851

Remove the

user = em.merge(user);

statement in your DAO destroy method. I am not sure if it causes the probem, but it is not needed because the user is loaded in the statement before.

Upvotes: 0

Related Questions