我们正在从MyBatis迁移到Spring Data JPA(使用hibernate)。最初,Spring配置将特定域级对象的util:map映射为枚举键引用的值。因此,地图被注入服务级别类。然后,此映射用于在流程流中基于特定枚举获取域级别对象。现在我们重构了服务层以使用支持Spring Data的@Entity域级对象,当我们尝试使用枚举键获取实体的实例时,它返回一个代理(正如您所期望的那样)。因此,当我们尝试使用返回的实例时,我们得到一个ClassCastException(由:java.lang.ClassCastException:com.sun.proxy引起。$ Proxy43不能转换为com.ourpackage.Event)。我的问题是:如何将@Entity类注入到util:map配置中,以便设置更多属性?
以下是实体对象和枚举查找键的映射配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<!--*********************************************************************-->
<!-- Event bean definitions -->
<!--*********************************************************************-->
<bean id="workEvent" class="com.ourpackage.Event">
<constructor-arg name="action" type="java.lang.String" value="action"/>
<constructor-arg name="type" type="java.lang.String" value="type"/>
<constructor-arg name="description" type="java.lang.String" value="A description"/>
</bean>
<!--*********************************************************************-->
<!-- Event Maps -->
<!--*********************************************************************-->
<util:map id="workEvents" map-class="java.util.HashMap" key-type="com.anotherpackage.EventType" value-type="com.ourpackage.Event">
<entry>
<key><value type="com.anotherpackage.EventType">WORK_ITEM</value></key>
<ref local="workEvent"/>
</entry>
</util:map>
</beans>
这是实体域类定义:
package com.ourpackage;
import static javax.persistence.GenerationType.IDENTITY;
import static javax.persistence.TemporalType.TIMESTAMP;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.transaction.annotation.Transactional;
import com.basepackage.ServiceEntity;
/**
* The Class Event.
*
*/
@Entity
@Table(name = "events")
@Transactional(readOnly = true)
public class Event extends ServiceEntity {
....
}
以下是使用此地图的服务类的代码:
// The following line produces the ClassCastException
workEvent = workEvents.get(EventType.WORK_ITEM);
当然可以通过废弃依赖注入配置并简单地动态构建Event类来解决这个问题,但是配置是首选方法。
非常感谢任何帮助。
答案 0 :(得分:3)
问题是具体类不再是com.ourpackage.Event
,因为Spring在其中包含了com.sun.proxy.$Proxy43
类型的代理,并且不可能将代理转换为事件,因为它们是两个完全不同的类型。
要解决此问题,请将事件实现为接口并强制转换为该接口,而不是强制转换为具体类。
通常,在大量使用代理/ AOP(如Spring / Hibernate应用程序)的应用程序中避免转换为具体类型通常是一种很好的做法。