2015-12-21 46 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