JPA Entity - Specify Persistence Unit?
Asked Answered
W

3

13

I have a JavaEE project that makes use of multiple persistence units. Is there any way to specify which persistence unit a particular JPA Entity belongs to? Some entities are in one data source, while others are in my second data source. Is there a way to differentiate between the two using annotations?

Wallis answered 25/4, 2013 at 0:39 Comment(0)
Y
11

To specify which persistent unit an Entity belongs to, use the persistence.xml file:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="user" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/myApp</jta-data-source>
        <class>com.company.User</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <!-- properties -->
        </properties>
    </persistence-unit>

    <persistence-unit name="data" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/myApp_data</jta-data-source>
        <!--<mapping-file>META-INF/myApp_entities.xml</mapping-file> You can also use mapping files.-->
        <class>com.company.Data</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <!-- properties -->
        </properties>
    </persistence-unit>
</persistence>

Note the use of <exclude-unlisted-classes />.

Yokefellow answered 25/4, 2013 at 2:13 Comment(3)
So this would require me to add every entity to persistence.xml, rather than using annotations for discovery, correct?Wallis
Yes. Fundamentally, in order to have a choice between persistence contexts, you will need to list all the classes in each persistence.xml, OR list the persistence context in each entity. Both seem the same amount of work. With the first, however, all metadata is in a single place.Yokefellow
Also, I'm not aware that the second method (listing persistent contexts in entities) is possible.Yokefellow
D
2

Also you can identify from which persistent unit an entity belongs by identifying the EntityManager that registered it.

A managed entity belongs to a persistence context, and a persistent context belongs to a persistence unit. So in this example:

@PersistenceContext(unitName="persistence-unit-1")
EntityManager em1;

@PersistenceContext(unitName="persistence-unit-2")
EntityManager em2;

em1.persist(entity1);
em2.persist(entity2);

entity1 belongs to persistence-unit-1 and entity2 belongs to persistence-unit-2. It's not so explicit like specifying the <class> tags in persistence.xml, but you can have the same entity classes in both persistent units and still differentiate to which unit each entity instance belongs.

Drawtube answered 25/4, 2013 at 22:20 Comment(5)
So how did you specify that entity1 belongs to persistence-unit-1, if you did not specify it with <class> tags in persistence.xml?Chirrup
@Chirrup when deploying the application to a full JEE container like Weblogic, JBoss or Webshpere, the application server takes care of auto scanning the classes that are annotated with "Entity", you don't need to add the <class> tags to persistence.xml like you do when using a servlet container like Tomcat or a standalone java application, unles you use the "exclude-unlisted-classes" tag.Drawtube
I know. but how does it know, to which persistence-unit it belongs to? Look answer abouve...Chirrup
The JPA spec doesn't specify it, but I'm pretty sure all classes belong to all persistence units if you don't specify "exclude-unlisted-classes=true". I understand that you don't want to add them to persistence.xml explicitly. Is there a problem if all classes are in all persistence units? If they're for different database schemas you can still specify the pu name on the EntityManager or EntityManagerFactory to connect to the right database, like I posted in this answer. Having a class available in the wrong persistence unit shouldn't be a problem unless you use automatic schema generationDrawtube
You wrote: Having a class available in the wrong persistence unit shouldn't be a problem unless you use automatic schema generation - is this also true for scheme validation? OK, I could check that. I did not thought so far that it could not hurt... if it really does not, it would be good news! Thanks!Chirrup
C
1

The @PersistenceUnit should be usable as well (I haven't tried it, yet, though)

e.g.

@PersistenceUnit(unitName="persistenceUnit2")
@Entity
class XPTO {
}

From the Javadoc (http://docs.oracle.com/javaee/6/api/javax/persistence/PersistenceUnit.html)

"Expresses a dependency on an EntityManagerFactory and its associated persistence unit."

unitName (Optional) The name of the persistence unit as defined in the persistence.xml file.

Cowry answered 31/7, 2015 at 16:30 Comment(7)
Can somebody confirm that this works? I have different entities which I like to assign to two different PersistentUnits - without exclude-unlisted-classes=trueChirrup
@badera: I haven't used it, I know it exists but in the end I never needed it. There's nothing like a quick test I guess :)Ancilla
Well, I tested it and it did not work [sorry, I did not mention it in the comment :)]. So I wonder if I have done something wrong or it really does not work. I would still be glad for a solution, where I can annotate each entity, to which PersistenceUnit (one or more) they shall belong to without listing all entity classes in the persistence.xml... this is annoying for few hundreds entities... even for less.Chirrup
@badera: so, you tried to define another persistance unit on the persistence.xml and use that @PersistenceUnit(unitName="newName") and what doesn't work exactly? you can always try to debug the code and see what's wrong with thatAncilla
Sorry, but debugging this is hard since I just see that this annotation has no effect. So why has it no effect? With no effect I mean it behaves as if I do not annotate @PersistenceUnit() on the @Entity. All the entities belong to all the persistence units, if exclude-unlisted-classes is false. I use Wildfly 8.2.1 with the included hibernate. I think I must downvote this answer, since it is an nonworing advice. Or please bring a proof that it works.Chirrup
@Chirrup it seems like this is how it works: github.com/wicketstuff/core/wiki/… and a more in depth explanation: doanduyhai.wordpress.com/2011/11/21/… So, apparently one needs to annotate the entity manager factory instead of the entity. I haven't read through the second in depth post, but it seems to have the key to how to use thisAncilla
I tested it also, and it doesn't work. The entity is pulled into all persistence units not just the one specified by the @PersistenceUnit annotation. I guess the purpose of the @PersistenceUnit annotation is not to annotate entities.Punk

© 2022 - 2024 — McMap. All rights reserved.