Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dealing with Single PersistenceUnit in Multiple persistence.xml files [SPR-2598] #7287

Closed
spring-issuemaster opened this issue Sep 18, 2006 · 7 comments

Comments

@spring-issuemaster
Copy link
Collaborator

commented Sep 18, 2006

Gary Ip opened SPR-2598 and commented

Features request for dealing with Dealing with Single PersistenceUnit in Multiple persistence.xml files as stated in Spring forum.
http://forum.springframework.org/showthread.php?t=29230

suggestion:

  1. allow the method preparePersistenceUnitInfos () in org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager to handle duplicated by adding ManagedClasses to the original one.
  2. or make this method to be easily overrided by opening the "readPersistenceUnitInfos()", etc.

Affects: 2.0 RC4

2 votes, 4 watchers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 20, 2007

Simon Lebettre commented

I too needed to merge the different persistence units having the same name in all my project jars,
but adding managedClasses did not work for me because in my setup it's hibernate Ejb3Configuration class wich scans the annotaions / managed entities.

It was working when I was manually adding the jars files in persistence.xml with <jar-file> :

So I made a custom PersistenceUnitManager based on DefaultPersistenceUnitManager with a hack to add all encountered "jars" to the persistence unit. (it works in source mode too because <jar-file> / JarFileUrls accepts directories too)

I had to copy and mod DefaultPersistenceUnitManager source and to keep it in package org.springframework.orm.jpa.persistenceunit (DefaultPersistenceUnitManager makes use of some default access classes, we can rename the class but we can not change the package)

public class MergePersistenceUnitManager {
[...]

        /* the modded method : */
           public void preparePersistenceUnitInfos() {
	[...]			
		mergePersistenceUnits(name,pui);
					
		this.persistenceUnitInfos.put(name, pui);
                  }
            }


        /*the new method : */

/**

  • MergePersistenceUnits

  • We add all persistenceunits Rooturls as jars in the final unique persistenceunit that will be in use.

  • Later, Hibernate Ejb3Configuration will scan all the jars and find all our entities.

  • But warning : if we add some specific config in persistence.xml, only the last persistence.xml will be taken,

  • this hack only give us access to the jars and entities.

  • @param persistenceUnitName to find previous pui in the persistenceUnitInfos map

  • @param pui where to add the Jars entries

  • @author http://www.linkedin.com/in/simonlebettre
    */
    private void mergePersistenceUnits(final String persistenceUnitName,final SpringPersistenceUnitInfo pui){

      //System.out.println("JarFileUrls : "+pui.toString() + " "+pui.getJarFileUrls());
    
      pui.addJarFileUrl(pui.getPersistenceUnitRootUrl());
    
      SpringPersistenceUnitInfo oldPui = (SpringPersistenceUnitInfo) this.persistenceUnitInfos.get(persistenceUnitName);
      if (oldPui != null) {
      	List<URL> urls = oldPui.getJarFileUrls();
      	for (URL url : urls) {
      		pui.addJarFileUrl(url);	
      	}				
      }	
    

    }

and here is how i use it in my config :

<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.MergePersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
[...]

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 21, 2007

Juergen Hoeller commented

I've added a protected "MutablePersistenceUnitInfo getPersistenceUnitInfo" method to DefaultPersistenceUnitManager, to allow for better subclassing. In combination with the existing "postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo)" template method, this should allow for implementing any such merging of units.

So your code as indicated above could look like as follows, sitting in any custom package:

public class CustomPersistenceUnitManager extends DefaultPersistenceUnitManager {

protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
super.postProcessPersistenceUnitInfo(pui);
pui.addJarFileUrl(pui.getPersistenceUnitRootUrl());

MutablePersistenceUnitInfo oldPui = getPersistenceUnitInfo(pui.getPersistenceUnitName());
if (oldPui != null) {
   List<URL> urls = oldPui.getJarFileUrls();
   for (URL url : urls) {
     pui.addJarFileUrl(url);
   }
}

}
}

Note that MutablePersistenceUnitInfo is a public type, whereas SpringPersistenceUnitInfo is internal. MutablePersistenceUnitInfo should give you anything you need for customization purposes, so that shouldn't restrict you at all - just operate on a MutablePersistenceUnitInfo in your code.

This should be available in tonight's Spring 2.0.4 snapshot (http://www.springframework.org/snapshots). Please give it a try and let me know whether it works for you!

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 22, 2007

Simon Lebettre commented

Great, it works fine with latest snapshot "spring-framework-2.0.4-20070322-${build.number}.zip" :

  • PersistenceUnits with the same name have their jars correctly added .
  • if a PersistenceUnit with another name is found it is correctly excluded .

Simon
( http://www.linkedin.com/in/simonlebettre )

@spring-issuemaster

This comment has been minimized.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 14, 2011

Florian Huonder commented

Hi all,

I have a question to Jürgen's code snippet.

Is this needed?:
MutablePersistenceUnitInfo oldPui = getPersistenceUnitInfo(pui.getPersistenceUnitName());
if (oldPui != null) {
List<URL> urls = oldPui.getJarFileUrls();
for (URL url : urls) { pui.addJarFileUrl(url); }
}

Those URL's are alread in the pui object?
In my opinion the pui and the oldPui objects are the same?
Am I missing something?

Regards,
Florian

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 15, 2011

Juergen Hoeller commented

It's about merging - there is a new and an old PersistenceUnitInfo object for the same persistence unit name. We're copying the old unit's jar file URLs into the new one. That new pui object will then eventually get registered under the shared persistence unit name, replacing the old object.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Mar 11, 2013

Neale Upstone commented

Juergen,

I notice that MergingPersistenceUnitManager is now part of Spring Data JPA. Would it not be better to move this to Spring ORM, now that it is part of a Spring project?

Cheers,

Neale

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.