使用EntityManager验证实体的唯一性

时间:2014-06-11 15:01:30

标签: java mysql hibernate jpa

我有一个User Entity类,它在MySQL数据库中映射User表。这是使用Eclipse中的Hibernate Tools自动生成的。

然后,我写了一个通用的DAO接口:

package dal.genericdao;
public interface GenericDAO <EntityClass, IDClass> {

    EntityClass create(EntityClass entity);

    void delete(IDClass id);

    EntityClass findById(IDClass id);

    EntityClass update(EntityClass entity);   
}

GenericDAOImpl类中实现,该类使用EntityManager进行CRUD操作。这是它的片段

package dal.genericdao;

import javax.persistence.PersistenceContext;

public class GenericDAOImpl<EntityClass, IDClass> implements GenericDAO<EntityClass, IDClass> {

    @PersistenceContext private EntityManager entityManager;


// ---- In the original post I omitted this piece of code for shortness. It only retrieves the runtime EntityClass ----
    private Class<EntityClass> entityClass;

    @SuppressWarnings("unchecked")
    public GenericDAOImpl() {
        entityClass = (Class<EntityClass>) ((ParameterizedType) getClass().getGenericSuperclass())
                        .getActualTypeArguments()[0];
    }

// --------------

    @Override
    public EntityClass create(EntityClass entity)
    {
        entityManager.getTransaction().begin();
        entityManager.persist(entity);
        entityManager.flush();
        entityManager.getTransaction().commit();

        return entity;
    }


    @Override
    public void delete(IDClass id)
    {
        ...
    }

    @Override
    public EntityClass findById(IDClass id)
    {
        ...
    }

    @Override
    public EntityClass update(EntityClass entity)
    {
        ...
    }


}

所以UserDAO就是这个

import dal.genericdao.GenericDAOImpl;
import dal.User;
import javax.enterprise.inject.Default;

@Default
public class UserDAO extends GenericDAOImpl<User, String> {
}

如果我在UserDAO类上运行一些测试,一切都按预期工作。

当我尝试持久存在(通过UserDAO.create()方法)数据库中已存在的Entity时,问题就会显示出来。实际上,entityManager.persist(entity)方法并不警告我是否持久存在的实体(理论上应该引发主键约束违反)。

此外,在entityManager.persist(entity)方法中,我无法访问Entity标识符值,因为它与通用IDClass类“隐藏”(因此我无法运行GenericDAOImpl.findById(IDClass)在持久操作之前验证Entity是否存在。

您如何看待这个问题?你会如何解决这个问题?

谢谢

2 个答案:

答案 0 :(得分:0)

考虑使用Spring框架。 Spring-Data-JPA项目具有出色的Repository实现。除其他功能外,它们还可以消除检查现有实体的负担。

答案 1 :(得分:0)

考虑在User表中使用除ID以外的唯一字段,并在该字段上保留之前进行检查。例如,它可以是用户名或几个字段的组合。