4

My question:

Is there a way to tell Spring/JPA to automatically detect classes annotated with @Entity?

Background:

This is my configuration of the entityManagerFactory

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
</bean>

... and this is my persistence.xml ...

<persistence-unit name="foo">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <properties>
    <property name="hibernate..." value="..."/>
    <property ...
  </properties>
</persistence-unit>

This configuration is working. But: When I add the following line to my entityManagerFactory configuration

<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />

JPA doesn't find my classes annotated with @Entity. So, I get Exceptions like this one:

java.lang.IllegalArgumentException: Unknown entity: foo.Bar

where foo.Bar is a class annotated with @javax.persistence.Entity

When I now add

<class>foo.Bar</class>

to my persistence.xml, everything's fine again. But why do I have to specify my classes in persistence.xml when using persistenceXmlLocation and otherwise not?

Note: You might ask why I want to use persistenceXmlLocation: It would solve this problem.

Community
  • 1
  • 1
Ethan Leroy
  • 15,804
  • 9
  • 41
  • 63
  • I found another solution for my problem. I simply moved all connection parameters from persistence.xml to spring's bean configuration. With this I can use a single persistence.xml for testing, development and production and don't have to provide persistenceXmlLocation. Nevertheless I want to know why the es are required when using persistenceXmlLocation and otherwise not. – Ethan Leroy Aug 09 '11 at 08:48
  • Hi @Ethan Leroy can you provide me the details on how you maintained different database connection parmas for prod and dev in spring bean config? It would be a great help. – ngCoder May 03 '17 at 09:55

3 Answers3

2

You didn't say exactly what was where, so maybe I'm wrong, but it looks like you feel into the trap I fell into. The location of the persistence.xml file defines where Spring (or any JPA provider) will look for @Entity classes by default. From the JPA spec, section 8.2.1

A persistence.xml file defines a persistence unit. The persistence.xml file is located in the META-INF directory of the root of the persistence unit. It may be used to specify managed persistence classes included in the persistence unit, object/relational mapping information for those classes, and other configuration information for the persistence unit and for the entity manager(s) and entity manager factory for the persistence unit. This information may be defined by containment or by reference, as described below.

The object/relational mapping information can take the form of annotations on the managed persistence classes included in the persistence unit, an orm.xml file contained in the META-INF directory of the root of the persistence unit, one or more XML files on the classpath and referenced from the persistence.xml file, or a combination of these. The managed persistence classes may either be contained within the root of the persistence unit; or they may be specified by reference—i.e., by naming the classes, class archives, or XML mapping files (which in turn reference classes) that are accessible on the application classpath; or they may be specified by some combination of these means.

So although the field is called persistenceXmlLocation, it probably should be called persistenceXmlName, because the purpose is to be able to create a persistence.xml file with a non-standard name so that the EE container will not pick it up. It still serves as the marker for where to look for Entity classes.

Old Pro
  • 24,624
  • 7
  • 58
  • 106
0

(From Y.Lev) When the entityManagerFactory bean in spring-beans.xml comes with location property and also with 'classpath:' directive: It doesn't matter where in the class path (When in eclipse put under [bin] or [build]) to put it.

1) Under eclipse: persistence.xml under \WebContent\WEB-INF\classes\persistence.xml
2) Under Tomcat : persistence.xml under \WEB-INF\classes\persistence.xml
3) When not in WEB project put anywhere under [bin] or [build].

<bean id="entityManagerFactory" 
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      lazy-init="false" p:dataSource-ref="dataSource">
    <property name="persistenceUnitName" value="empPU" />
    <property name="persistenceXmlLocation" value="classpath:persistence.xml"/>
</bean>     

The persistence.xml file Should be MANUALLY COPIED somewhere under classpath ..\bin\persistence.xml OTHERWISE it is ignored !!!

Y.Lev
  • 1
  • 1
-1

For the following exception: Caused by: javax.persistence.PersistenceException: Unable to resolve persistence unit root URL at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl(DefaultPersistenceUnitManager.java:452) at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.preparePersistenceUnitInfos(DefaultPersistenceUnitManager.java:343) at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.afterPropertiesSet(DefaultPersistenceUnitManager.java:325) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:224) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) ... 14 more

In my case, the jar itself included withing it the META-INF/persistence.xml which Spring was not finding given the hint:

Finally, I did the following:

java -classpath ".;my-jarThatIncludesTheMetaInfPersistence.jar" main arguments...

and the trick was adding the "." to the classpath. Then spring found the xml file in the classpath.

99Sono
  • 3,554
  • 27
  • 39
  • Looks like another issue that has nothing to do with my question here. – Ethan Leroy Feb 25 '15 at 15:36
  • Lol, probably posted on the wrong stack overflow tab, when I was googling why spring was returning avax.persistence.PersistenceException: Unable to resolve persistence unit root URL . :) Sorry for that. – 99Sono Feb 27 '15 at 16:50
  • In any case, as for entity detection, I suppose that you are well aware that in the persistence.xml under a persistence unit you have both and elements, right? http://docs.oracle.com/cd/E19798-01/821-1841/bnbrj/index.html Class is fine grained and faster. Jar-file is coarse grained and low maintenance. Cheers. – 99Sono Feb 27 '15 at 17:00