2009-07-15 2 views
21

Я пытаюсь настроить Spring JPA Hibernate простой пример WAR для развертывания в Glassfish. Я вижу, что в некоторых примерах используется файл persistence.xml, а в других примерах нет. В некоторых примерах используется dataSource, а некоторые нет. До сих пор я понимаю, что DataSource не требуется, если у меня есть:Spring JPA и persistence.xml

<persistence-unit name="educationPU" 
    transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <class>com.coe.jpa.StudentProfile</class> 
    <properties> 
     <property name="hibernate.connection.driver_class" 
      value="com.mysql.jdbc.Driver" /> 
     <property name="hibernate.connection.url" 
      value="jdbc:mysql://localhost:3306/COE" /> 
     <property name="hibernate.connection.username" value="root" /> 
     <property name="show_sql" value="true" /> 
     <property name="dialect" value="org.hibernate.dialect.MySQLDialect" /> 
    </properties> 
</persistence-unit> 

Я могу развернуть хорошо, но мой EntityManager не получает впрыскивается Spring.

Мои applicationContext.xml:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="educationPU" /> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="StudentProfileDAO" class="com.coe.jpa.StudentProfileDAO"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

<bean id="studentService" class="com.coe.services.StudentService"> 
</bean> 

Мой класс с EntityManager:

public class StudentService { 
private String saveMessage; 
private String showModal; 
private String modalHeader; 
private StudentProfile studentProfile; 
private String lastName; 
private String firstName; 

@PersistenceContext(unitName="educationPU") 
private EntityManager em; 

@Transactional 
public String save() 
{ 
    System.out.println("*** em: " + this.em); //em is null 
    this.studentProfile= new StudentProfile(); 
    this.saveMessage = "saved"; 
    this.showModal = "true"; 
    this.modalHeader= "Information Saved"; 
    return "successs"; 
} 

Мой web.xml:

<listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 

Есть ли части I не хватает т o что Spring прикладывает «em» к StudentService?

ответ

12

Просто, чтобы подтвердить, что Вы, вероятно, сделал ...

ли вы включить

<!-- tell spring to use annotation based congfigurations --> 
<context:annotation-config /> 
<!-- tell spring where to find the beans --> 
<context:component-scan base-package="zz.yy.abcd" /> 

биты в прикладном context.xml?

Также я не уверен, что вы сможете использовать тип транзакции jta с такой настройкой? Разве это не потребует пула подключений с источником данных? Поэтому попробуйте RESOURCE_LOCAL.

0

У меня есть тестовое приложение настроено с помощью JPA/Hibernate & Spring, и моя конфигурация отражает твою с тем исключением, что я создать источник данных и впрыскивать его в EntityManagerFactory и переместил специфические свойства DataSource из persistenceUnit и в источник данных. С этими двумя небольшими изменениями мой EM получает инъекцию должным образом.

4

Я смущен. Вы вводите PU в сервисный слой, а не в слой persistence? Я этого не понимаю.

Я добавляю слой сохранения в сервисный слой. Уровень обслуживания содержит бизнес-логику и демаркирует границы транзакций. Он может включать более одного DAO в транзакцию.

Я не получаю магию в вашем методе save(). Как сохраняются данные?

В производстве настроить пружину так:

<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/ThePUname" /> 

вместе со ссылкой на веб.XML

Для модульного тестирования я делаю это:

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:dataSource-ref="dataSource" p:persistence-xml-location="classpath*:META-INF/test-persistence.xml" 
    p:persistence-unit-name="RealPUName" p:jpaDialect-ref="jpaDialect" 
    p:jpaVendorAdapter-ref="jpaVendorAdapter" p:loadTimeWeaver-ref="weaver"> 
</bean> 
0

Это может быть старый, но если кто-то имеет такую ​​же проблему, попробуйте изменить UnitName только имя в PersistenceContext аннотацию:

От

@PersistenceContext(unitName="educationPU") 

в

@PersistenceContext(name="educationPU") 
+7

А? Необязательный атрибут 'name'' @ PersistenceContext' используется для поиска инъецируемого менеджера объектов. ** У него нет соответствующего элемента в 'persistence.xml' **. Если это сработало для вас, это ИМО - просто удачный побочный эффект, связанный с отсутствием 'unitName' (поведение в этом случае зависит от поставщика). Но это неверно. –

0

Если кто-то хочет использовать чисто конфигурации Java вместо xml конфигурации спящего режима, используйте:

Вы можете настроить спящий режим без использования persistence.xml вообще весной, как например:

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() 
{ 
Map<String, Object> properties = new Hashtable<>(); 
properties.put("javax.persistence.schema-generation.database.action", 
"none"); 
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); 
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB 
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
factory.setJpaVendorAdapter(adapter); 
factory.setDataSource(this.springJpaDataSource()); 
factory.setPackagesToScan("package name"); 
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE); 
factory.setValidationMode(ValidationMode.NONE); 
factory.setJpaPropertyMap(properties); 
return factory; 
} 

Поскольку вы не используете persistence.xml, вы должны создать компонент, который возвращает DataSource, указанный вами в указанном выше методе, который устанавливает источник данных:

@Bean 
public DataSource springJpaDataSource() 
{ 
DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa"); 
dataSource.setUsername("tomcatUser"); 
dataSource.setPassword("password1234"); 
return dataSource; 
} 

Затем вы используете аннотацию @EnableTransactionManagement над этим конфигурационным файлом. Теперь, когда вы поставите эту аннотацию, вы должны создать один последний компонент:

@Bean 
public PlatformTransactionManager jpaTransactionManager() 
{ 
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject()); 
} 

Теперь, не забудьте использовать @Transactional аннотации по тому способу, что дело с БД.

И, наконец, не забудьте ввести EntityManager в ваш репозиторий (этот класс хранилища должен содержать @Repository аннотации по нему).

Смежные вопросы