Как внедрить @PersistenceContext в DAO, сгенерированный Hibernate3-maven-plugin
Я хочу создать Java-приложение на основе Hibernate-3 и Spring Framework. Чтобы упростить процесс, я нашел hibernate3-maven-plugin, который может выполнить реверс-инжиниринг существующей базы данных.
Вот пример POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<components>
<component>
<name>hbm2java</name>
<outputDirectory>src/main/java</outputDirectory>
<implementation>jdbcconfiguration</implementation>
</component>
<component>
<name>hbm2dao</name>
<outputDirectory>src/main/java</outputDirectory>
<implementation>jdbcconfiguration</implementation>
</component>
</components>
<componentProperties>
<revengfile>/src/main/resources/model.reveng.xml</revengfile>
<propertyfile>/src/main/resources/hibernate.properties</propertyfile>
<jdk5>true</jdk5>
<ejb3>true</ejb3>
</componentProperties>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>hbm2java</goal>
<goal>hbm2dao</goal>
</goals>
</execution>
</executions>
</plugin>
Затем я установил контекст Spring:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="gomer" />
</bean>
<bean id="entityManager" factory-bean="entityManagerFactory" factory-method="createEntityManager"/>
<bean id="user" class="ru.tomtrix.first.db.UserHome">
<property name="entityManager" ref="entityManager"/>
</bean>
</beans>
Он прекрасно генерирует файл Entity и файл DAO, за исключением следующего. В файле DAO есть EntityManager:
@Stateless
public class UserHome {
private static final Log log = LogFactory.getLog(UserHome.class);
@PersistenceContext private EntityManager entityManager;
... и у этого поля нет сеттера! В конце концов Spring выдает исключение:
Invalid property 'entityManager' of bean class [ru.tomtrix.first.db.UserHome]: Bean property 'entityManager' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Конечно, не рекомендуется писать установщик вручную. Я думаю, что есть способ правильно ввести менеджер. Так как же это сделать без перезаписи сгенерированного файла?
Соответствующая информация:
1) Я хотел бы создать отдельное приложение (и, возможно, запустить его на сервере приложений, таком как Tomcat)
2) model.reveng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering SYSTEM "http://www.hibernate.org/dtd/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
<table-filter match-name=".*" package="ru.tomtrix.first.db"/>
</hibernate-reverse-engineering>
3) persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="gomer" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>User</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/users"/>
</properties>
</persistence-unit>
</persistence>
1 ответ
Проблема в том, что вам не хватает части конфигурации. Вы должны сообщить Spring, что вы хотите (также) использовать аннотации для конфигурации. Для этого добавьте <context:annotation-config />
к вашей конфигурации и удалите настройку entityManager
После этого удалите вызов фабричного метода, пружина будет обрабатывать все это за вас.
Добавлен совет использовать схемы без версии
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="gomer" />
</bean>
<bean id="user" class="ru.tomtrix.first.db.UserHome" />
</beans>
Ваш код может быть проблематичным, когда вы развертываете его на полноценном сервере приложений, и у вас могут возникнуть проблемы с Spring и EJB-контейнером, конкурирующими за контроль над bean-компонентами. Плагин гибернации генерирует @Stateless
сессионные компоненты, которые в общем случае будут подхвачены приложением. сервер (в зависимости от того, какой вы используете).