"Cannot read files twice on NativeScanner" exception when using multiple persistence.xml

Description

When subclassing DefaultPersistenceUnitManager as described in http://ancientprogramming.blogspot.com/2007/05/multiple-persistencexml-files-and.html in order to have my entities in different jars, Hibernate 3.5-Beta3 throw the following exception (it worked with previous version of Hibernate) :

java.lang.RuntimeException: error trying to scan <jar-file>: file:/Users/bouiaw/resthub/resthub-core/target/classes/
at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:700)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:465)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:165)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1457)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1397)
... 51 more
Caused by: org.hibernate.AssertionFailure: Cannot read files twice on NativeScanner
at org.hibernate.ejb.packaging.NativeScanner.getFilesInJar(NativeScanner.java:168)
at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:393)
at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:697)
... 57 more

Environment

None

Activity

Show:
Vincent MATHON
April 6, 2010, 5:00 PM

I use the same code as Bouiaw pointed out. To deal with hibernate 3.5.0-Final I simply override org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager#obtainPersistenceUnitInfo as follow:

@Override
public PersistenceUnitInfo obtainPersistenceUnitInfo(String persistenceUnitName) {
PersistenceUnitInfo persistenceUnitInfo = super.obtainPersistenceUnitInfo(persistenceUnitName);
persistenceUnitInfo.getJarFileUrls().remove(persistenceUnitInfo.getPersistenceUnitRootUrl());
return persistenceUnitInfo;

}

Under the cover, I ask spring to process all META-INF/persistence-spring.xml files (I have renamed persistence.xml files to avoid interferences with JPA engines) in the classpath using the same code as the one at http://ancientprogramming.blogspot.com/2007/05/multiple-persistencexml-files-and.html . I end with a merged persistence unit whose root url is the one of the last processed persistence-spring.xml file. The JarFileUrls collection of this merged persistence unit also contains the root URL and hibernate 3.5.x does not allow to process a jar twice as previous versions did. Withdrawing the root URL from the JarFileUrls when possible solves the issue.

Bouiaw
April 6, 2010, 10:08 PM

On our side, we implemented at Spring level a ScanningPersistenceManager, source code available on http://bitbucket.org/ilabs/resthub/src/tip/resthub-core/src/main/java/org/resthub/core/domain/dao/jpa/ScanningPersistenceUnitManager.java

Emmanuel Bernard
April 8, 2010, 10:35 AM

I'll mark the bug as won't fix because this is really a misuse of the library and the JPA packaging semantic (see http://lists.jboss.org/pipermail/hibernate-dev/2010-February/004813.html ).

subes
April 12, 2010, 12:01 AM

This works for me:

@NotThreadSafe
public class MergedPersistenceUnitManager extends DefaultPersistenceUnitManager {

@Override
protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo newPU) {
super.postProcessPersistenceUnitInfo(newPU);
/* ++ changed ++ treat RootPU as Jar and remove RootPU so its not duplicate */
newPU.addJarFileUrl(newPU.getPersistenceUnitRootUrl());
newPU.setPersistenceUnitRootUrl(null);
/* – changed – */
final String persistenceUnitName = newPU.getPersistenceUnitName();
final PersistenceUnitInfo oldPU = getPersistenceUnitInfo(persistenceUnitName);
if (oldPU != null) {
List<URL> urls = oldPU.getJarFileUrls();
for (URL url : urls) {
newPU.addJarFileUrl(url);
}
List<String> managedClassNames = oldPU.getManagedClassNames();
for (String managedClassName : managedClassNames) {
newPU.addManagedClassName(managedClassName);
}
List<String> mappingFileNames = oldPU.getMappingFileNames();
for (String mappingFileName : mappingFileNames) {
newPU.addMappingFileName(mappingFileName);
}
Properties oldProperties = oldPU.getProperties();
Properties newProperties = newPU.getProperties();
newProperties.putAll(oldProperties);
newPU.setProperties(newProperties);
}
}

}

Steve Ebersole
March 21, 2011, 7:09 PM

Bulk closing stale resolved issues

Won't Fix

Assignee

Unassigned

Reporter

Bouiaw

Fix versions

None

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure