HHH-8775 - Exception when mapping a class more than once - applying tests from https://github.com/hibernate/hibernate-orm/pull/677 + fix

This commit is contained in:
Steve Ebersole 2015-11-04 20:32:46 -06:00
parent eadb0fec8f
commit 1a2bdd09e8
6 changed files with 149 additions and 10 deletions

View File

@ -101,6 +101,11 @@ public class CallbackRegistryImpl implements CallbackRegistry {
}
}
@Override
public boolean hasRegisteredCallbacks(Class entityClass, Class annotationClass) {
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( annotationClass );
return map != null && map.containsKey( entityClass );
}
/**
* Great care should be taken calling this. Not a fan of it being public, but that is needed because of

View File

@ -51,6 +51,18 @@ public class LegacyCallbackProcessor implements CallbackProcessor {
final XClass entityXClass = reflectionManager.classForName( entityClassName );
final Class entityClass = reflectionManager.toClass( entityXClass );
for ( Class annotationClass : CALLBACK_ANNOTATION_CLASSES ) {
if ( callbackRegistry.hasRegisteredCallbacks( entityClass, annotationClass ) ) {
// this most likely means we have a class mapped multiple times using the hbm.xml
// "entity name" feature
log.debugf(
"CallbackRegistry reported that Class [%s] already had %s callbacks registered; " +
"assuming this means the class was mapped twice " +
"(using hbm.xml entity-name support) - skipping subsequent registrations",
entityClassName,
annotationClass.getSimpleName()
);
continue;
}
final Callback[] callbacks = resolveCallbacks( entityXClass, annotationClass, reflectionManager );
callbackRegistry.addEntityCallbacks( entityClass, annotationClass, callbacks );
}

View File

@ -12,17 +12,19 @@ import java.io.Serializable;
* @author Steve Ebersole
*/
public interface CallbackRegistry extends Serializable {
public void preCreate(Object entity);
public boolean hasPostCreateCallbacks(Class entityClass);
public void postCreate(Object entity);
void preCreate(Object entity);
boolean hasPostCreateCallbacks(Class entityClass);
void postCreate(Object entity);
public boolean preUpdate(Object entity);
public boolean hasPostUpdateCallbacks(Class entityClass);
public void postUpdate(Object entity);
boolean preUpdate(Object entity);
boolean hasPostUpdateCallbacks(Class entityClass);
void postUpdate(Object entity);
public void preRemove(Object entity);
public boolean hasPostRemoveCallbacks(Class entityClass);
public void postRemove(Object entity);
void preRemove(Object entity);
boolean hasPostRemoveCallbacks(Class entityClass);
void postRemove(Object entity);
public boolean postLoad(Object entity);
boolean postLoad(Object entity);
boolean hasRegisteredCallbacks(Class entityClass, Class annotationClass);
}

View File

@ -0,0 +1,31 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.callbacks.hbmxml;
/**
* @author Steve Ebersole
*/
public class Entity {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.callbacks.hbmxml;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.jpa.boot.spi.Bootstrap;
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
/**
* @author Felix Feisst (feisst dot felix at gmail dot com)
*/
public class MappingClassMoreThanOnceTest extends BaseUnitTestCase {
/**
* Tests that an entity manager can be created when a class is mapped more than once.
*/
@Test
@TestForIssue(jiraKey = "HHH-8775")
// @FailureExpected(jiraKey = "HHH-8775")
public void testBootstrapWithClassMappedMOreThanOnce() {
Map settings = new HashMap( );
settings.put( AvailableSettings.HBXML_FILES, "org/hibernate/jpa/test/callbacks/hbmxml/ClassMappedMoreThanOnce.hbm.xml" );
final EntityManagerFactoryBuilder builder = Bootstrap.getEntityManagerFactoryBuilder(
new BaseEntityManagerFunctionalTestCase.TestingPersistenceUnitDescriptorImpl( getClass().getSimpleName() ),
settings
);
HibernateEntityManagerFactory emf = null;
try {
emf = builder.build().unwrap( HibernateEntityManagerFactory.class );
}
finally {
if ( emf != null ) {
try {
emf.close();
}
catch (Exception ignore) {
}
}
}
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.jpa.test.callbacks.hbmxml">
<class entity-name="Entity1" name="Entity" table="ENTITY1">
<id name="id" column="id" type="long">
<generator class="native"/>
</id>
<property name="name" type="string">
<column name="NAME" length="20" not-null="true"/>
</property>
</class>
<class entity-name="Entity2" name="Entity" table="ENTITY2">
<id name="id" column="id" type="long">
<generator class="native"/>
</id>
<property name="name" type="string">
<column name="NAME" length="20" not-null="true"/>
</property>
</class>
</hibernate-mapping>