Spring Данные JPA - инъекция зависимостей конкретного класса сущностей

Мы переносимся с MyBatis на Spring Data JPA (используя спящий режим). Первоначально конфигурация Spring указывала использование: map определенных объектов уровня домена как значения, на которые ссылался ключ enum. Таким образом, карта была введена в класс уровня обслуживания. Затем эта карта использовалась для получения объекта уровня домена на основе определенного перечисления во время потока процесса. Теперь мы отредактировали уровень сервиса для использования Spring Объектов уровня домена с включенной поддержкой данных @Entity, когда мы пытаемся получить экземпляр объекта с использованием ключа enum, он возвращает прокси (как и следовало ожидать). Таким образом, когда мы пытаемся использовать возвращаемый экземпляр, мы получаем ClassCastException (Caused by: 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">
 <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">
 </constructor-arg></constructor-arg></constructor-arg></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">
 </ref></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 "на лету", однако предпочтительным вариантом является конфигурация.

Любая помощь будет принята с благодарностью.

1 ответ

Проблема заключается в том, что конкретный класс больше не является com.ourpackage.Event, потому что Spring завернул в него прокси типа com.sun.proxy.$Proxy43, и невозможно передать прокси для события, потому что это два совершенно разных типа.

Чтобы решить эту задачу, создайте событие, реализуя интерфейс и применяя его к этому интерфейсу, вместо того, чтобы использовать конкретный класс.

В целом рекомендуется избегать литья конкретных типов в приложениях, которые широко используют прокси-сервер/AOP (например, приложения Spring/Hibernate).

licensed under cc by-sa 3.0 with attribution.