我有一个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
是否存在。
您如何看待这个问题?你会如何解决这个问题?
谢谢
答案 0 :(得分:0)
考虑使用Spring框架。 Spring-Data-JPA项目具有出色的Repository实现。除其他功能外,它们还可以消除检查现有实体的负担。
答案 1 :(得分:0)
考虑在User表中使用除ID以外的唯一字段,并在该字段上保留之前进行检查。例如,它可以是用户名或几个字段的组合。