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

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 entityName
			event.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);
	}
最后注册事件:
@Component
public class MyEventListenerRegistry {
	@Autowired
	private SessionFactory sessionFactory;
	
	/**
	 * イベントリスナーを登録する
	 */
	@PostConstruct
	public void registerListeners() {
		// イベントリスナーを管理するサービスを取得する
		EventListenerRegistry serviceRegistry = ((SessionFactoryImpl) sessionFactory)
		      .getServiceRegistry().getService(EventListenerRegistry.class);
		// Loadイベントのリスナーを登録する
		serviceRegistry.prependListeners(EventType.LOAD, new EneresLoadEventListener());
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值