Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA - multiple jars defining @Entity objects

Tags:

We are developing a web application with Spring, Hibernate and Maven in a very modular fashion. There are core projects defining data access and view specific stuff, then there are modules defining logic and entities (@Entity) and then there's the web app defining controller and view.

Now we have a security module defining security entities like account and role and we have a prototype module defining some example entities like customer and order. Both have a PersistenceUnit defined inside a persistence.xml which is pretty much empty except for the PersistenceUnit name, as all database configuration is done in the web app with a datasource.xml. The web app is supposed to load both jars as maven dependencies.

Both projects will build fine, autocscanning all entities and creating them for their respective unit tests. They will also get loaded inside the web app successfully if added individually.

However, as soon as both are loaded at the same time, the second one will override the PersistenceUnit of the first one and thus create an IllegalArgumentException : Not an entity for all entities from the first one. If both projects have a different persistence unit, loading the web app will throw another exception saying that no single default persistence unit defined.

So.. how can I get all @Entity annotated classes to load up in my web app without having to define them all inside the persistence.xml (like here) but rather via component scan? This seems like an idea, though I don't know how to use and test it...

I think we either have to merge all PersistenceUnits inside the web app or load all Entities programmatically. Defining them hard-coded inside the persistence.xml is not an option for us.

like image 604
Pete Avatar asked Sep 16 '11 09:09

Pete


People also ask

Can a JPA entity have multiple Onetomany associations?

You can have multiple one-to-many associations, as long as only one is EAGER.

What does @ID do in JPA?

Simple Identifiers The most straightforward way to define an identifier is by using the @Id annotation. Simple ids are mapped using @Id to a single property of one of these types: Java primitive and primitive wrapper types, String, Date, BigDecimal and BigInteger.

Can we have an entity without @ID JPA?

If your object does not have an id, but its' table does, this is fine. Make the object an Embeddable object, embeddable objects do not have ids. You will need a Entity that contains this Embeddable to persist and query it.

What is the @entity annotation?

The @Entity annotation specifies that the class is an entity and is mapped to a database table. The @Table annotation specifies the name of the database table to be used for mapping.


2 Answers

Since the question seems to still get attention, I'll post our latest solution to the problem.

We are now auto-scanning all packages instead of using persistence.xml files anywhere.

In our datasource.xml we added the line

<property name="packagesToScan" value="our.basepackage" /> 

Almost complete datasource.xml:

<!-- Bean definition here -->  <bean id="ourDataSource"     class="org.springframework.jdbc.datasource.DriverManagerDataSource">     <property name="driverClassName" value="com.mysql.jdbc.Driver" />             <!-- define connection properties -->        </bean>   <bean id="entityManagerFactory"     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">     <property name="dataSource" ref="ourDataSource" />     <property name="packagesToScan" value="our.basepackage" />     <property name="jpaVendorAdapter">         <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">             <property name="showSql" value="false" />             <property name="generateDdl" value="true" />             <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />         </bean>     </property>  </bean>  <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" /> 

like image 105
Pete Avatar answered Oct 29 '22 12:10

Pete


We use a similar module layout, but we place the persistence context in the war-part of our application and inject the entitymanager into the DAOs of the modules. Except for unit testing, the modules don't have a PU. We did this because we were afraid, that a transaction spanning multiple modules could cause trouble.

In the DAO

@PersistenceContext private EntityManager em; 

In the persistance.xml you need to enlist all entities with the elements.

<persistence-unit name="myPU">     <class>com.Entity1</class>       <class>com.Entity2</class> 

etc.

like image 26
stacker Avatar answered Oct 29 '22 14:10

stacker