2015-12-21 42 views
1

我遇到了genericDao和model Interface的一些问题。具有接口模型对象的通用Hibernate Dao

我采取了以下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(); 
} 
... 

这适用于 “正常” 的对象完全没有问题。

我试图使用接口类型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; 
} 

我实例化IBattery通过Spring的ApplicationContext文件加载SimulationBattery实现。 它适用于持续存在,列表(标准),但未能与负载的“getById”的原因,发送:

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

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

谢谢。

Fabien。

(我使用Hibernate,Spring和Java8)

回答

1

当你坚持下去的实体,您通过一个具体的实体实例休眠。因此,Hibernate接收SimulationBattery的一个实例,从而知道您持续存在的实体的类型:SimulationBattery。当您列出时,您依赖于Hibernate的多态特性:您要求Hibernate返回IBattery的所有实体实例。 Hibernate知道实现此接口的所有具体实体类(例如SimulationBattery和ProductionBattery)。所以它从数据库中加载它们,并返回它们。

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

+0

谢谢你的解释。所以,最后,我必须重写SpringMVC注入并手动完成。这太令人沮丧了...... – MilacH