【项目课题】Hibernate的一对一关系联合主键ID类不同而引起的错误

来源:互联网 发布:js复合保温图集 编辑:程序博客网 时间:2024/06/06 21:35

hibernate 的保存,更新,删除都是通过触发一系列相关事件来处理的,对于一对一关系,在A表a,b为联合主键对应hibernate实体为A.id,B表中a,b同样联合主键对应hibernate实体为B.id且a,b的外键关联A表于是就有了一对一关系。

当取得对象B的时候触发DefaultLoadEventListener时间处理,这时传过来的ID,为A.id,但是在B的对象生成的时候确实需要B.id出现类型不匹配

解决方案:重写DefaultLoadEventListener修改事件传过来的A.id为B.id

代码

public class MyLoadEventListener extends DefaultLoadEventListener {/** * serialVersionUID */private static final long serialVersionUID = -3129774467686995363L;/** * HibernateのLoadイベントを呼び出す前に、 * 実体クラスのIDインスタンスをLoadイベントのIDインスタンスの代わりにする * * @param event Loadイベント * @param loadType Load種別 * @throws HibernateException */@Override@SuppressWarnings(Constant.UNCHECKED)public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException {// イベントの呼び出す元final SessionImplementor source = event.getSession();// 実体クラスを取得するEntityPersister persister;if (event.getInstanceToLoad() != null) {persister = source.getEntityPersister(null, event.getInstanceToLoad());//the load() which takes an entity does not pass an entityNameevent.setEntityClassName(event.getInstanceToLoad().getClass().getName());} else {persister = source.getFactory().getEntityPersister(event.getEntityClassName());}if (persister == null) {throw new HibernateException("Unable to locate persister: " + event.getEntityClassName());}// 実体クラスのIDクラスfinal Class<Serializable> idClass = persister.getIdentifierType().getReturnedClass();// LoadイベントのIDインスタンスが実体クラスではない場合、// 実体クラスのIDインスタンスをLoadイベントのIDインスタンスの代わりにするif (idClass != null && !idClass.isInstance(event.getEntityId())) {Serializable id = null;try {// 実体クラスのIDクラスより、実体クラスのIDインスタンスを生成するid = (Serializable) idClass.newInstance();// LoadイベントのIDインスタンスより、、実体クラスに属性の値をコピーするBeanUtils.copyProperties(event.getEntityId(), id);} catch (Exception e) {// 異常が発生する場合、異常の情報しかを出力しないthrow new TypeMismatchException("Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass+ ", got " + event.getEntityId().getClass());}// 実体クラスのIDインスタンスをLoadイベントに設定するevent.setEntityId(id);}// HibernateのLoadイベントを呼び出すsuper.onLoad(event, loadType);}
最后注册事件:
@Componentpublic class MyEventListenerRegistry {@Autowiredprivate SessionFactory sessionFactory;/** * イベントリスナーを登録する */@PostConstructpublic void registerListeners() {// イベントリスナーを管理するサービスを取得するEventListenerRegistry serviceRegistry = ((SessionFactoryImpl) sessionFactory)      .getServiceRegistry().getService(EventListenerRegistry.class);// Loadイベントのリスナーを登録するserviceRegistry.prependListeners(EventType.LOAD, new EneresLoadEventListener());}}


0 0
原创粉丝点击