Spring JPA и persistence.xml - PullRequest
       18

Spring JPA и persistence.xml

23 голосов
/ 15 июля 2009

Я пытаюсь настроить простой пример WAR JPA Hibernate для развертывания на Glassfish. Я вижу, что некоторые примеры используют файл 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.

Мое приложениеContext.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>

Есть ли какие-то элементы, которые мне не хватает, чтобы Spring вставлял "em" в StudentService?

Ответы [ 5 ]

13 голосов
/ 16 июля 2009

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

Вы включили

<!--  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.

4 голосов
/ 07 августа 2009

Я в замешательстве. Вы внедряете PU в слой обслуживания, а не в уровень персистентности? Я не понимаю этого.

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

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

На производстве я настраиваю пружину так:

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

вместе со ссылкой в ​​web.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>
1 голос
/ 06 апреля 2017

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

Вы можете настроить Hibernate без использования файла persistence.xml в Spring следующим образом:

@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, вы должны создать bean-компонент, который возвращает 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 над ним).

0 голосов
/ 14 июля 2010

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

С

@PersistenceContext(unitName="educationPU")

до

@PersistenceContext(name="educationPU")
0 голосов
/ 16 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...