2009-07-15 35 views
21

Tôi đang cố thiết lập một ví dụ đơn giản về Spring JPA Hibernate WAR để triển khai cho Glassfish. Tôi thấy một số ví dụ sử dụng tệp persistence.xml và các ví dụ khác thì không. Một số ví dụ sử dụng dataSource, và một số thì không. Cho đến nay, hiểu biết của tôi là không cần có dataSource nếu tôi có:Spring JPA và 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> 

Tôi có thể triển khai tốt, nhưng EntityManager của tôi không được Spring tiêm vào.

My 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> 

lớp của tôi với 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 của tôi:

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

Có bất kỳ mảnh tôi thiếu t o có Spring tiêm "em" vào StudentService không?

Trả lời

12

Chỉ để xác nhận mặc dù bạn có thể đã làm ...

Bạn đã bao gồm các

<!-- 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" /> 

bit trong context.xml ứng dụng của bạn?

Ngoài ra tôi không chắc bạn có thể sử dụng loại giao dịch jta với loại thiết lập này không? Điều đó sẽ không yêu cầu một hồ bơi kết nối được quản lý nguồn dữ liệu? Vì vậy, hãy thử RESOURCE_LOCAL để thay thế.

0

Tôi có một ứng dụng thử nghiệm được thiết lập bằng cách sử dụng JPA/Hibernate & Mùa xuân và cấu hình của tôi phản ánh bạn ngoại trừ việc tôi tạo nguồn dữ liệu và tiêm vào EntityManagerFactory và di chuyển các thuộc tính cụ thể của nguồn dữ liệu ra khỏi persistenceUnit và nguồn dữ liệu. Với hai thay đổi nhỏ này, EM của tôi được tiêm đúng cách.

4

Tôi đang bối rối. Bạn đang tiêm một PU vào lớp dịch vụ và không phải là lớp kiên trì? Tôi không hiểu.

Tôi đưa lớp kiên trì vào lớp dịch vụ. Tầng dịch vụ chứa logic nghiệp vụ và phân định ranh giới giao dịch. Nó có thể bao gồm nhiều hơn một DAO trong một giao dịch.

Tôi cũng không nhận được phép màu trong phương thức save() của bạn. Dữ liệu được lưu như thế nào?

Trong sản xuất nào để cấu hình mùa xuân như thế này:

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

cùng với các tài liệu tham khảo trong web.xml

Đối với kiểm tra đơn vị tôi làm điều này:

<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

Đây có thể là cũ, nhưng nếu có ai có cùng một vấn đề hãy thử thay đổi unitName để chỉ tên trong chú thích PersistenceContext:

Từ

@PersistenceContext(unitName="educationPU") 

đến

@PersistenceContext(name="educationPU") 
+7

Huh? Thuộc tính 'name' tùy chọn của' @ PersistenceContext' được sử dụng để tìm kiếm trình quản lý thực thể được tiêm. ** Nó không có phần tử tương ứng trong 'persistence.xml' **. Nếu điều này làm việc cho bạn, đây là IMO chỉ là một tác dụng phụ may mắn liên quan đến sự vắng mặt của 'unitName' (hành vi trong trường hợp này là nhà cung cấp cụ thể). Nhưng điều này không đúng. –

0

Nếu bất cứ ai muốn sử dụng thuần túy cấu hình Java thay vì cấu hình xml độ hibernate, sử dụng này:

Bạn có thể cấu hình Hibernate mà không sử dụng persistence.xml ở tất cả trong mùa xuân như thế này:

@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; 
} 

Vì bạn không sử dụng persistence.xml, bạn nên tạo một bean trả về DataSource mà bạn chỉ định trong phương thức trên thiết lập nguồn dữ liệu:

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

Sau đó, bạn sử dụng chú thích @EnableTransactionManagement trên tệp cấu hình này. Bây giờ khi bạn đặt chú thích rằng, bạn phải tạo một hạt đậu cuối cùng:

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

Bây giờ, đừng quên sử dụng @Transactional Chú trên những phương pháp mà đối phó với DB.

Cuối cùng, đừng quên tiêm EntityManager vào kho lưu trữ của bạn (Lớp lưu trữ này phải có chú thích @Repository trên đó).

Các vấn đề liên quan