-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Multiple Persistence.xml
PostPosted: Wed Jun 27, 2007 1:37 pm 
Newbie

Joined: Mon Sep 19, 2005 8:11 pm
Posts: 5
Here is a hack to allow multiple persistence.xmls. Why do i want different persistence.xmls? cos i have different sets of entities that belong to different dbs and different cvs modules.

Found this spring solution: http://forum.springframework.org/showthread.php?t=26365
but im not using spring.

I am using the spring.jar for the PathMatchingResourcePatternResolver so i can find the different persistence.xml in the different jars. There may be a better way of doing this

Code:
   /**
    *
    * Source 1: http://forum.springframework.org/showthread.php?t=26365
    * Source 2: http://www.hibernate.org/386.html?cmd=comphist&histnode=2844
    * @throws Exception
    */
   private static void hackInit() throws Exception {
      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
      Resource[] resources = resolver.getResources("classpath*:META-INF/persistence.xml");

      for (Resource resource : resources) {
          if (resource.getURL().getProtocol().equals("file")) {
             VzLogger.info("Found Persistence.xml: " + resource.getFile().getCanonicalPath());
             URL classpathRoot = new URL("file:"+determineClasspathRootDir(resource, "META-INF/persistence.xml"));
             
             List<PersistenceMetadata> persistenceMetadatas = PersistenceXmlLoader.deploy(resource.getURL(), new HashMap(), new EJB3DTDEntityResolver());
             for(PersistenceMetadata metadata : persistenceMetadatas){
//                 Configure our EJB3 EntityManagerFactory
                 Ejb3Configuration ejbconf = new Ejb3Configuration();
                 for(Entry entry : metadata.getProps().entrySet()){
                    ejbconf.setProperty(entry.getKey().toString(), entry.getValue().toString());
                 }
                
//                 Find all our persistent classes from persistence.jar
                 JarVisitor.Filter[] filters = new JarVisitor.Filter[2];
                 filters[0] = new JarVisitor.PackageFilter( false, null ) {
                     public boolean accept(String javaElementName) {
                         return true;
                     }
                 };
                 filters[1] = new JarVisitor.ClassFilter(
                         false, new Class[]{
                         Entity.class,
                         MappedSuperclass.class,
                         Embeddable.class}
                 ) {
                     public boolean accept(String javaElementName) {
                         return true;
                     }
                 };

//                 Add all persistent classes found to EJB3 config
                 JarVisitor j = JarVisitor.getVisitor(classpathRoot, filters);
                 Set<JarVisitor.Entry>[] entries = (Set<JarVisitor.Entry>[])j.getMatchingEntries();
                 for (int i = 0; i < entries.length; i++)
                 {
                     for (JarVisitor.Entry c : entries[i])
                     {
                         VzLogger.debug("Found entity " + c.getName());
                         ejbconf.addAnnotatedClass(Class.forName(c.getName()));
                     }
                 }
//               Add any classes stated in the config file
                 for(String string : metadata.getClasses()){
                      VzLogger.debug("Persistence.xml entity " + string);
                      ejbconf.addAnnotatedClass(Class.forName(string));                    
                 }
                 //Use depricated because of http://forum.hibernate.org/viewtopic.php?t=967615
                 EntityManagerFactory emf = ejbconf.createEntityManagerFactory();
//Save emf to a map
                 VzLogger.info("Added EntityManagerFactory: " + metadata.getName());
             }

          }
      }         
   }
   
    protected static String determineClasspathRootDir(Resource resource, String classpathMarkerFile) throws IOException {
        String location = resource.getFile().getAbsolutePath();
        return location.substring(0, location.length()-classpathMarkerFile.length());
    }     


I have not tested this in a production env


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 29, 2007 11:02 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Exactly why <jar-file> in persistence.xml doesn't work?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 03, 2007 6:27 am 
Newbie

Joined: Mon Sep 19, 2005 8:11 pm
Posts: 5
Minor correction otherwise it wont work with JAR files.
Code:
   private static void hackInit(Resource[] resources, PersistenceStrategyFactory factory) throws Exception {
      for (Resource resource : resources) {
          VzLogger.info("Found Persistence.xml: " + resource.getURL());
          URL classpathRoot = determineClasspathRootDir(resource, PersistenceConstants.EJB_PERSISTENCE_CONFIG_FILE);
          
          List<PersistenceMetadata> persistenceMetadatas = PersistenceXmlLoader.deploy(resource.getURL(), new HashMap(), new EJB3DTDEntityResolver());
          for(PersistenceMetadata metadata : persistenceMetadatas){
             //Configure our EJB3 EntityManagerFactory
              Ejb3Configuration ejbconf = new Ejb3Configuration();
              for(Entry entry : metadata.getProps().entrySet()){
                 ejbconf.setProperty(entry.getKey().toString(), entry.getValue().toString());
              }
             
              //Find all our persistent classes from persistence.jar
              JarVisitor.Filter[] filters = new JarVisitor.Filter[2];
              filters[0] = new JarVisitor.PackageFilter( false, null ) {
                  public boolean accept(String javaElementName) {
                      return true;
                  }
              };
              filters[1] = new JarVisitor.ClassFilter(
                      false, new Class[]{
                      Entity.class,
                      MappedSuperclass.class,
                      Embeddable.class}
              ) {
                  public boolean accept(String javaElementName) {
                      return true;
                  }
              };

              //Add all persistent classes found to EJB3 config
              JarVisitor j = JarVisitor.getVisitor(classpathRoot, filters);
              Set<JarVisitor.Entry>[] entries = (Set<JarVisitor.Entry>[])j.getMatchingEntries();
              for (int i = 0; i < entries.length; i++)
              {
                  for (JarVisitor.Entry c : entries[i])
                  {
                      //VzLogger.debug("Found entity " + c.getName());
                      ejbconf.addAnnotatedClass(Class.forName(c.getName()));
                  }
              }
              //Add any classes stated in the config file
              for(String string : metadata.getClasses()){
                   //VzLogger.debug("Persistence.xml entity " + string);
                   ejbconf.addAnnotatedClass(Class.forName(string));                    
              }
              //Use depricated because of http://forum.hibernate.org/viewtopic.php?t=967615
              EntityManagerFactory emf = ejbconf.createEntityManagerFactory();
              EJBPersistenceUtil.INSTANCE.addEntityManagerFactory(metadata.getName(), emf);
              factory.addStrategyCreator(new EJBStrategyCreator(metadata.getName()));
              VzLogger.info("Added Persistence Unit: " + metadata.getName());
          }
      }         
   }
   
    protected static URL determineClasspathRootDir(Resource resource, String classpathMarkerFile) throws IOException {
        String location = resource.getURL().toString();
        int index = location.lastIndexOf("!");
        if(index != -1){
           return    JarVisitor.getJarURLFromURLEntry(resource.getURL(), classpathMarkerFile);
        }else{
           return new URL(location.substring(0, location.length()-classpathMarkerFile.length()));
      }
    }     


I dont want to use <jar-file> as a dont have Jar files in my workspace


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 03, 2007 11:44 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
It works with directories too

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 10, 2007 9:40 am 
Newbie

Joined: Mon Sep 19, 2005 8:11 pm
Posts: 5
Lets say i have two sets of entities. SetA and SetB. I have two cvs modules SetAEntities and SetBEntities. My build process will create two jars SetAEntities.jar and SetBEntities.jar. I have divided these entities as they are related to two different databases.

If im understanding what your saying correctly your saying i should have a single persistence.xml that references the difference sets. Inside that persistence.xml i would then need two persistence units for each database. And i would need one persistence.xml for the workspace (referencing directories) and another for the build (referencing jars).

To me it makes sense to keep the persistence.xml separate, one of my sets is used more than the other and it makes sense to not have to repeat the persistence unit all around the place.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 2:09 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
OK I did not understand you problem.
So if you have 2 sets of entities stored in 2 different databases, you need 2 Persistence units.
You can put the persistence.xml in each jar file (hence 2 persistence.xml files) with 2 different persistence unit names.

But then you don't need to "merge" them, the Persistence class will do the job of creating the right EMF for a given PU name even if you have different jars

_________________
Emmanuel


Top
 Profile  
 
 Post subject: What about Scripts and unit tests
PostPosted: Tue Jul 22, 2008 10:30 am 
Newbie

Joined: Tue Jan 11, 2005 6:48 am
Posts: 7
Hello,

on the same subject, how do you make persistence units available only on specific configurations? I mean, I would like to write unit tests pointing to an in-memory hypersonic database but I don't want this PersistenceUnit deployed (and usable) in my J2EE application. Just want to be able to load it in my tests.

Same problem goes with a J2SE script that has to update your Database outside of your application server scope. In this case, I want to access the same database (the production one) but, since I am outside of the J2EE world, I have to configure my database in a different way... and again, I don't want to have this PersistenceUNit accessible from my WebApplication server.

Is it possible to specify another file as "Persistence.xml" to load persistence information from? If not, why? Am I asking for something stupid?

Thank you very much in advance for your replies.

Jer


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 22, 2008 11:00 am 
Newbie

Joined: Tue Jan 11, 2005 6:48 am
Posts: 7
Hello again!

I don't know if it will help but, checking in the Hibernate-entityManager source code, I found, in the org.hibernate.ejb.Ejb3Configuration class -called by HibernatePersistence class to create its configuration, the following code:



public Ejb3Configuration configure(String persistenceUnitName, Map integration)
{
try
{
log.debug( "Look up for persistence unit: " + persistenceUnitName );
integration = integration == null ?CollectionHelper.EMPTY_MAP :Collections.unmodifiableMap( integration );
Enumeration<URL> xmls = Thread.currentThread().getContextClassLoader().getResources( "META-INF/persistence.xml" );
if ( ! xmls.hasMoreElements() )
{
log.info( "Could not find any META-INF/persistence.xml file in the classpath");
}



the "persistence.xml" file is here directly referenced... meaning that there is probably no simple way to just use a configuration file with another name.

Is there a reason for this?
Again, if my question is stupid, don't hesitate to tell me why - I am really stuck on that one and would like to have my tests and scripts done elegantly ;-)

Thank you very much for the time taken,

Jérôme


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.