views:

50

answers:

1

I have one persistence unit configured in my persistence.xml but i have two databases. Those databases are identical, regarding the schema. What i am trying to do is:

Persistence.createEntityManagerFactory("unit", primaryProperties);
Persistence.createEntityManagerFactory("unit", secondaryProperties);

The properties contain different connection settings (user, password, jdbc url, ...).
I tried this actually and it seems that hibernate (my jpa provider) returns the same instance in the second call, without taking care of the properties.

Do i need to copy the configuration to a second unit?


I nailed it down to something different than i thought before. The EntityManagers (and Factories) returned by the calls above work as expected, but getDelegate() seems to be the problem. I need to get the underlying session to support legacy code in my application which relies directly on the hibernate api. What i did is:

final Session session = (Session) manager.getDelegate();

But somehow i receive a session operating on the primary database even when using an entitymanager which operates on the second.

+2  A: 

This is weird. According to the sources of HibernateProvider#createEntityManagerFactory, the method returns an new instance:

public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
    Ejb3Configuration cfg = new Ejb3Configuration();
    Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties );
    return configured != null ? configured.buildEntityManagerFactory() : null;
}

And I definitely don't get the same instances in this dummy test:

@Test
public void testCreateTwoDifferentEMF() {
    Map properties1 = new HashMap();
    EntityManagerFactory emf1 = Persistence.createEntityManagerFactory("MyPu", properties1);
    Map properties2 = new HashMap();
    properties2.put("javax.persistence.jdbc.user", "foo");
    EntityManagerFactory emf2 = Persistence.createEntityManagerFactory("MyPu", properties2);
    assertFalse(emf1 == emf2); //passes
}

Actually, it just works (and the second instance is using the overridden properties).

Pascal Thivent
I had similar issues trying to do the same for EclipseLink. The best I could do is simply using the same datasource but different persistence units with the properties I wanted.
The Alchemist
@the-alchemist I don't know what to say :) First, the question is about Hibernate. Second, regardless of the implementation, the spec is clear (section 7.2.1 javax.persistence.Persistence Class): the method should return an EMF using the passed properties. Any other behavior is IMO a bug.
Pascal Thivent