通用Hibernate Dao与接口模型对象

时间:2015-12-21 20:24:10

标签: java spring hibernate

我遇到了genericDao和模型接口的一些问题。

我实现了以下GenericHibernateDao:

@Repository
public abstract class GenericHibernateDao<T, PK extends Serializable> implements IGenericDao<T, PK> {

@Autowired
private SessionFactory sessionFactory;

private Class<T> type;

@SuppressWarnings({ "unchecked", "rawtypes" })
public GenericHibernateDao() {
    Type t = getClass().getGenericSuperclass();
    ParameterizedType pt = (ParameterizedType) t;
    type = (Class) pt.getActualTypeArguments()[0];
}

public void setSessionFactory(SessionFactory sessionFactory){
    this.sessionFactory = sessionFactory;
}

@Transactional
public T add(T obj){
    getSession().persist(obj);
    return obj;
}

@Transactional
@SuppressWarnings("unchecked")
public T getById(PK id){
    T result = (T) getSession().load(type, id);
    return result;
}

@Transactional
@SuppressWarnings("unchecked")
public List<T> list(){
    Criteria crit = getSession().createCriteria(type);
    return (List<T>) crit.list();
}
...

这对于“普通”物体非常适用。

我正在尝试将Interface用作类型T(例如:IBattery):

public class BatteryDao extends GenericHibernateDao<IBattery, Integer> implements IBatteryDao {

}

-

public interface IBattery {

  public int getId();

  public double getLevel();
  public void setLevel(double _level);
}

-

@Entity
public class SimulationBattery implements IBattery {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(unique = true, nullable = false)
private int id;

@Column(unique = false, nullable = false)
private double level;

@Override
public int getId() {
    return id;
}

@Override
public double getLevel() {
    return level;
}

@Override
public void setLevel(double _level) {
    level = _level;
}

我通过Spring applicationContext文件实例化IBattery来加载SimulationBattery实现。 它适用于持久化,列表(带标准)但失败并带有“getById”导致加载,发送:

org.hibernate.MappingException: Unknown entity: ***.***.****.IBattery

这是正确的,因为只有实现(SimulationBattery)映射在hibernate.cfg.xml中,但我不明白为什么我可以添加,列表,但不加载... 有人有解释吗?

谢谢。

小煜。

(我正在使用Hibernate,Spring和Java8)

1 个答案:

答案 0 :(得分:1)

当你持久化实体时,你将一个具体的实体实例传递给Hibernate。因此,Hibernate接收一个SimulationBattery实例,因此知道您持久存在的实体的类型:SimulationBattery。

当你列出时,你依赖于Hibernate的多态特性:你要求Hibernate返回IBattery的所有实体实例。 Hibernate知道实现此接口的所有具体实体类(例如,SimulationBattery和ProductionBattery)。所以它从数据库中加载它们并返回它们。

但是当你通过ID请求一个特定的实体时,所有Hibernate都知道该实体是实现IBattery的实体之一,并且它的ID是你传递的实体(例如42)。这还不够。您可能想要SimulationBattery 42或ProductionBattery 42,而Hibernate不知道。因此失败了。