我遇到了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)
答案 0 :(得分:1)
当你持久化实体时,你将一个具体的实体实例传递给Hibernate。因此,Hibernate接收一个SimulationBattery实例,因此知道您持久存在的实体的类型:SimulationBattery。
当你列出时,你依赖于Hibernate的多态特性:你要求Hibernate返回IBattery的所有实体实例。 Hibernate知道实现此接口的所有具体实体类(例如,SimulationBattery和ProductionBattery)。所以它从数据库中加载它们并返回它们。
但是当你通过ID请求一个特定的实体时,所有Hibernate都知道该实体是实现IBattery的实体之一,并且它的ID是你传递的实体(例如42)。这还不够。您可能想要SimulationBattery 42或ProductionBattery 42,而Hibernate不知道。因此失败了。