HHH-11274 - EntityManagerFactoryImpl.getIdentifier uses deprecated version of getIdentifier
This commit is contained in:
parent
8002595e86
commit
3906816ee2
|
@ -11,9 +11,11 @@ import javax.persistence.PersistenceUnitUtil;
|
||||||
import javax.persistence.spi.LoadState;
|
import javax.persistence.spi.LoadState;
|
||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.engine.spi.ManagedEntity;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
|
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -59,12 +61,31 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getIdentifier(Object entity) {
|
public Object getIdentifier(Object entity) {
|
||||||
final Class entityClass = Hibernate.getClass( entity );
|
if ( entity == null ) {
|
||||||
final EntityPersister persister = sessionFactory.getMetamodel().entityPersister( entityClass );
|
throw new IllegalArgumentException( "Passed entity cannot be null" );
|
||||||
if ( persister == null ) {
|
}
|
||||||
throw new IllegalArgumentException( entityClass + " is not an entity" );
|
|
||||||
|
if ( entity instanceof HibernateProxy ) {
|
||||||
|
final HibernateProxy proxy = (HibernateProxy) entity;
|
||||||
|
return proxy.getHibernateLazyInitializer().getIdentifier();
|
||||||
|
}
|
||||||
|
else if ( entity instanceof ManagedEntity ) {
|
||||||
|
final ManagedEntity enhancedEntity = (ManagedEntity) entity;
|
||||||
|
return enhancedEntity.$$_hibernate_getEntityEntry().getId();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.debugf(
|
||||||
|
"javax.persistence.PersistenceUnitUtil.getIdentifier is only intended to work with enhanced entities " +
|
||||||
|
"(although Hibernate also adapts this support to its proxies); " +
|
||||||
|
"however the passed entity was not enhanced (nor a proxy).. may not be able to read identifier"
|
||||||
|
);
|
||||||
|
final Class entityClass = Hibernate.getClass( entity );
|
||||||
|
final EntityPersister persister = sessionFactory.getMetamodel().entityPersister( entityClass );
|
||||||
|
if ( persister == null ) {
|
||||||
|
throw new IllegalArgumentException( entityClass + " is not an entity" );
|
||||||
|
}
|
||||||
|
//TODO does that work for @IdClass?
|
||||||
|
return persister.getIdentifier( entity );
|
||||||
}
|
}
|
||||||
//TODO does that work for @IdClass?
|
|
||||||
return persister.getIdentifier( entity );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
package org.hibernate.tuple.entity;
|
package org.hibernate.tuple.entity;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||||
|
@ -175,6 +177,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
else {
|
else {
|
||||||
identifierMapperType = (CompositeType) mapper.getType();
|
identifierMapperType = (CompositeType) mapper.getType();
|
||||||
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
|
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
|
||||||
|
getFactory(),
|
||||||
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
|
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
|
||||||
(ComponentType) identifierMapperType
|
(ComponentType) identifierMapperType
|
||||||
);
|
);
|
||||||
|
@ -275,6 +278,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller;
|
private final MappedIdentifierValueMarshaller mappedIdentifierValueMarshaller;
|
||||||
|
|
||||||
private static MappedIdentifierValueMarshaller buildMappedIdentifierValueMarshaller(
|
private static MappedIdentifierValueMarshaller buildMappedIdentifierValueMarshaller(
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
ComponentType mappedIdClassComponentType,
|
ComponentType mappedIdClassComponentType,
|
||||||
ComponentType virtualIdComponent) {
|
ComponentType virtualIdComponent) {
|
||||||
// so basically at this point we know we have a "mapped" composite identifier
|
// so basically at this point we know we have a "mapped" composite identifier
|
||||||
|
@ -301,8 +305,9 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
return wereAllEquivalent
|
return wereAllEquivalent
|
||||||
? new NormalMappedIdentifierValueMarshaller( virtualIdComponent, mappedIdClassComponentType )
|
? new NormalMappedIdentifierValueMarshaller( virtualIdComponent, mappedIdClassComponentType )
|
||||||
: new IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
: new IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
||||||
virtualIdComponent,
|
sessionFactory,
|
||||||
mappedIdClassComponentType
|
virtualIdComponent,
|
||||||
|
mappedIdClassComponentType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +342,15 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
|
|
||||||
private static class IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller
|
private static class IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller
|
||||||
implements MappedIdentifierValueMarshaller {
|
implements MappedIdentifierValueMarshaller {
|
||||||
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
private final ComponentType virtualIdComponent;
|
private final ComponentType virtualIdComponent;
|
||||||
private final ComponentType mappedIdentifierType;
|
private final ComponentType mappedIdentifierType;
|
||||||
|
|
||||||
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
||||||
|
SessionFactoryImplementor sessionFactory,
|
||||||
ComponentType virtualIdComponent,
|
ComponentType virtualIdComponent,
|
||||||
ComponentType mappedIdentifierType) {
|
ComponentType mappedIdentifierType) {
|
||||||
|
this.sessionFactory = sessionFactory;
|
||||||
this.virtualIdComponent = virtualIdComponent;
|
this.virtualIdComponent = virtualIdComponent;
|
||||||
this.mappedIdentifierType = mappedIdentifierType;
|
this.mappedIdentifierType = mappedIdentifierType;
|
||||||
}
|
}
|
||||||
|
@ -353,25 +361,18 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
|
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
|
||||||
final Type[] subTypes = virtualIdComponent.getSubtypes();
|
final Type[] subTypes = virtualIdComponent.getSubtypes();
|
||||||
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
|
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
|
||||||
final Iterable<PersistEventListener> persistEventListeners = persistEventListeners( session );
|
|
||||||
final int length = subTypes.length;
|
final int length = subTypes.length;
|
||||||
for ( int i = 0; i < length; i++ ) {
|
for ( int i = 0; i < length; i++ ) {
|
||||||
if ( propertyValues[i] == null ) {
|
if ( propertyValues[i] == null ) {
|
||||||
throw new HibernateException( "No part of a composite identifier may be null" );
|
throw new HibernateException( "No part of a composite identifier may be null" );
|
||||||
}
|
}
|
||||||
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
//JPA 2 @MapsId + @IdClass points to the pk of the entity
|
||||||
if ( subTypes[i].isAssociationType() && !copierSubTypes[i].isAssociationType() ) {
|
if ( subTypes[i].isAssociationType() && !copierSubTypes[i].isAssociationType() ) {
|
||||||
// we need a session to handle this use case
|
|
||||||
if ( session == null ) {
|
|
||||||
throw new AssertionError(
|
|
||||||
"Deprecated version of getIdentifier (no session) was used but session was required"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
propertyValues[i] = determineEntityIdPersistIfNecessary(
|
propertyValues[i] = determineEntityIdPersistIfNecessary(
|
||||||
propertyValues[i],
|
propertyValues[i],
|
||||||
(AssociationType) subTypes[i],
|
(AssociationType) subTypes[i],
|
||||||
session,
|
session,
|
||||||
persistEventListeners
|
sessionFactory
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,7 +397,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName();
|
final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName();
|
||||||
final EntityKey entityKey = session.generateEntityKey(
|
final EntityKey entityKey = session.generateEntityKey(
|
||||||
(Serializable) extractedValues[i],
|
(Serializable) extractedValues[i],
|
||||||
session.getFactory().getMetamodel().entityPersister( associatedEntityName )
|
sessionFactory.getMetamodel().entityPersister( associatedEntityName )
|
||||||
);
|
);
|
||||||
// it is conceivable there is a proxy, so check that first
|
// it is conceivable there is a proxy, so check that first
|
||||||
Object association = persistenceContext.getProxy( entityKey );
|
Object association = persistenceContext.getProxy( entityKey );
|
||||||
|
@ -415,6 +416,9 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Iterable<PersistEventListener> persistEventListeners(SharedSessionContractImplementor session) {
|
private static Iterable<PersistEventListener> persistEventListeners(SharedSessionContractImplementor session) {
|
||||||
|
if ( session == null ) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
return session
|
return session
|
||||||
.getFactory()
|
.getFactory()
|
||||||
.getServiceRegistry()
|
.getServiceRegistry()
|
||||||
|
@ -427,62 +431,108 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
Object entity,
|
Object entity,
|
||||||
AssociationType associationType,
|
AssociationType associationType,
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session,
|
||||||
Iterable<PersistEventListener> persistEventListeners) {
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
if ( entity == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE : persist if necessary for proper merge support (HHH-11328)
|
||||||
|
// but only allow persist if a Session is passed (HHH-11274)
|
||||||
|
|
||||||
if ( HibernateProxy.class.isInstance( entity ) ) {
|
if ( HibernateProxy.class.isInstance( entity ) ) {
|
||||||
// entity is a proxy, so we know it is not transient; just return ID from proxy
|
// entity is a proxy, so we know it is not transient; just return ID from proxy
|
||||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
EntityEntry pcEntry = session.getPersistenceContext().getEntry( entity );
|
if ( session != null ) {
|
||||||
|
final EntityEntry pcEntry = session.getPersistenceContext().getEntry( entity );
|
||||||
if ( pcEntry != null ) {
|
if ( pcEntry != null ) {
|
||||||
// entity managed; return ID.
|
// entity managed; return ID.
|
||||||
return pcEntry.getId();
|
return pcEntry.getId();
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
final EntityPersister persister = session.getEntityPersister(
|
|
||||||
associationType.getAssociatedEntityName( session.getFactory() ),
|
final EntityPersister persister = resolveEntityPersister(
|
||||||
entity
|
entity,
|
||||||
);
|
associationType,
|
||||||
Serializable entityId = persister.getIdentifier( entity, session );
|
session,
|
||||||
if ( entityId == null ) {
|
sessionFactory
|
||||||
// entity is transient with no ID; we need to persist the entity to get the ID.
|
);
|
||||||
entityId = persistTransientEntity( entity, session, persistEventListeners );
|
|
||||||
|
Serializable entityId = persister.getIdentifier( entity, session );
|
||||||
|
|
||||||
|
if ( entityId == null ) {
|
||||||
|
if ( session != null ) {
|
||||||
|
// if we have a session, then follow the HHH-11328 requirements
|
||||||
|
entityId = persistTransientEntity( entity, session );
|
||||||
|
}
|
||||||
|
// otherwise just let it be null HHH-11274
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( session != null ) {
|
||||||
|
// if the entity is in the process of being merged, it may be stored in the
|
||||||
|
// PC already, but doesn't have an EntityEntry yet. If this is the case,
|
||||||
|
// then don't persist even if it is transient because doing so can lead
|
||||||
|
// to having 2 entities in the PC with the same ID (HHH-11328).
|
||||||
|
final EntityKey entityKey = session.generateEntityKey( entityId, persister );
|
||||||
|
if ( session.getPersistenceContext().getEntity( entityKey ) == null &&
|
||||||
|
ForeignKeys.isTransient(
|
||||||
|
persister.getEntityName(),
|
||||||
|
entity,
|
||||||
|
null,
|
||||||
|
session
|
||||||
|
) ) {
|
||||||
|
// entity is transient and it is not in the PersistenceContext.
|
||||||
|
// entity needs to be persisted.
|
||||||
|
persistTransientEntity( entity, session );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// entity has an ID.
|
|
||||||
final EntityKey entityKey = session.generateEntityKey( entityId, persister );
|
|
||||||
// if the entity is in the process of being merged, it may be stored in the
|
|
||||||
// PC already, but doesn't have an EntityEntry yet. If this is the case,
|
|
||||||
// then don't persist even if it is transient because doing so can lead
|
|
||||||
// to having 2 entities in the PC with the same ID (HHH-11328).
|
|
||||||
if ( session.getPersistenceContext().getEntity( entityKey ) == null &&
|
|
||||||
ForeignKeys.isTransient(
|
|
||||||
persister.getEntityName(),
|
|
||||||
entity,
|
|
||||||
null,
|
|
||||||
session
|
|
||||||
) ) {
|
|
||||||
// entity is transient and it is not in the PersistenceContext.
|
|
||||||
// entity needs to be persisted.
|
|
||||||
persistTransientEntity( entity, session, persistEventListeners );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entityId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EntityPersister resolveEntityPersister(
|
||||||
|
Object entity,
|
||||||
|
AssociationType associationType,
|
||||||
|
SharedSessionContractImplementor session,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
assert sessionFactory != null;
|
||||||
|
|
||||||
|
if ( session != null ) {
|
||||||
|
return session.getEntityPersister(
|
||||||
|
associationType.getAssociatedEntityName( session.getFactory() ),
|
||||||
|
entity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String entityName = null;
|
||||||
|
for ( EntityNameResolver entityNameResolver : sessionFactory.getMetamodel().getEntityNameResolvers() ) {
|
||||||
|
entityName = entityNameResolver.resolveEntityName( entity );
|
||||||
|
if ( entityName != null ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( entityName == null ) {
|
||||||
|
// old fall-back
|
||||||
|
entityName = entity.getClass().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionFactory.getMetamodel().entityPersister( entityName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Serializable persistTransientEntity(
|
private static Serializable persistTransientEntity(
|
||||||
Object entity,
|
Object entity,
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session) {
|
||||||
Iterable<PersistEventListener> persistEventListeners) {
|
assert session != null;
|
||||||
|
|
||||||
LOG.debug( "Performing implicit derived identity cascade" );
|
LOG.debug( "Performing implicit derived identity cascade" );
|
||||||
final PersistEvent event = new PersistEvent(
|
final PersistEvent event = new PersistEvent(
|
||||||
null,
|
null,
|
||||||
entity,
|
entity,
|
||||||
(EventSource) session
|
(EventSource) session
|
||||||
);
|
);
|
||||||
for ( PersistEventListener listener : persistEventListeners ) {
|
|
||||||
|
for ( PersistEventListener listener : persistEventListeners( session ) ) {
|
||||||
listener.onPersist( event );
|
listener.onPersist( event );
|
||||||
}
|
}
|
||||||
final EntityEntry pcEntry = session.getPersistenceContext().getEntry( entity );
|
final EntityEntry pcEntry = session.getPersistenceContext().getEntry( entity );
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class GetIdentifierTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {
|
||||||
|
LegacyEntity.class,
|
||||||
|
ModernEntity.class,
|
||||||
|
NestedLegacyEntity.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void dropData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getIdentifierTest() throws Exception {
|
||||||
|
EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
|
||||||
|
// This gives a NullPointerException right now. Look at HHH-10623 when this issue is fixed
|
||||||
|
Serializable nestedLegacyEntityId = (Serializable) entityManager.getEntityManagerFactory()
|
||||||
|
.getPersistenceUnitUtil().getIdentifier(createExisitingNestedLegacyEntity());
|
||||||
|
|
||||||
|
entityManager.getTransaction().commit();
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private NestedLegacyEntity createExisitingNestedLegacyEntity() {
|
||||||
|
|
||||||
|
ModernEntity modernEntity = new ModernEntity();
|
||||||
|
modernEntity.setFoo(2);
|
||||||
|
|
||||||
|
LegacyEntity legacyEntity = new LegacyEntity();
|
||||||
|
legacyEntity.setPrimitivePk1(1);
|
||||||
|
legacyEntity.setPrimitivePk2(2);
|
||||||
|
legacyEntity.setFoo("Foo");
|
||||||
|
|
||||||
|
NestedLegacyEntity nestedLegacyEntity = new NestedLegacyEntity();
|
||||||
|
nestedLegacyEntity.setModernEntity(modernEntity);
|
||||||
|
nestedLegacyEntity.setLegacyEntity(legacyEntity);
|
||||||
|
|
||||||
|
return nestedLegacyEntity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
|
||||||
|
@Entity(name = "LegacyEntity")
|
||||||
|
@IdClass(LegacyEntityPk.class)
|
||||||
|
public class LegacyEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private int primitivePk1;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private int primitivePk2;
|
||||||
|
|
||||||
|
private String foo;
|
||||||
|
|
||||||
|
public LegacyEntity() {}
|
||||||
|
|
||||||
|
public int getPrimitivePk1() {
|
||||||
|
return primitivePk1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimitivePk1(int primitivePk1) {
|
||||||
|
this.primitivePk1 = primitivePk1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrimitivePk2() {
|
||||||
|
return primitivePk2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimitivePk2(int primitivePk2) {
|
||||||
|
this.primitivePk2 = primitivePk2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFoo() {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoo(String foo) {
|
||||||
|
this.foo = foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
LegacyEntity that = (LegacyEntity) o;
|
||||||
|
|
||||||
|
if (primitivePk1 != that.primitivePk1) return false;
|
||||||
|
return primitivePk2 == that.primitivePk2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = primitivePk1;
|
||||||
|
result = 31 * result + primitivePk2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LegacyEntity{" +
|
||||||
|
"primitivePk1=" + primitivePk1 +
|
||||||
|
", primitivePk2=" + primitivePk2 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class LegacyEntityPk implements Serializable {
|
||||||
|
|
||||||
|
private int primitivePk1;
|
||||||
|
|
||||||
|
private int primitivePk2;
|
||||||
|
|
||||||
|
public LegacyEntityPk() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrimitivePk1() {
|
||||||
|
return primitivePk1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimitivePk1(int primitivePk1) {
|
||||||
|
this.primitivePk1 = primitivePk1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrimitivePk2() {
|
||||||
|
return primitivePk2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimitivePk2(int primitivePk2) {
|
||||||
|
this.primitivePk2 = primitivePk2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
LegacyEntityPk that = (LegacyEntityPk) o;
|
||||||
|
|
||||||
|
if (primitivePk1 != that.primitivePk1) return false;
|
||||||
|
return primitivePk2 == that.primitivePk2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = primitivePk1;
|
||||||
|
result = 31 * result + primitivePk2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity(name = "ModernEntity")
|
||||||
|
public class ModernEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private int foo;
|
||||||
|
|
||||||
|
public ModernEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFoo() {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoo(int foo) {
|
||||||
|
this.foo = foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ModernEntity that = (ModernEntity) o;
|
||||||
|
|
||||||
|
return id == that.id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ModernEntity{" +
|
||||||
|
"id=" + id +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinColumns;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity(name = "NestedLegacyEntity")
|
||||||
|
@IdClass(NestedLegacyEntityPk.class)
|
||||||
|
public class NestedLegacyEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumns({@JoinColumn(name = "legacyFk1", referencedColumnName = "primitivePk1"),
|
||||||
|
@JoinColumn(name = "legacyFk2", referencedColumnName = "primitivePk2")})
|
||||||
|
private LegacyEntity legacyEntity;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "modernFk", referencedColumnName = "id")
|
||||||
|
private ModernEntity modernEntity;
|
||||||
|
|
||||||
|
public NestedLegacyEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyEntity getLegacyEntity() {
|
||||||
|
return legacyEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegacyEntity(LegacyEntity legacyEntity) {
|
||||||
|
this.legacyEntity = legacyEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModernEntity getModernEntity() {
|
||||||
|
return modernEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModernEntity(ModernEntity modernEntity) {
|
||||||
|
this.modernEntity = modernEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
NestedLegacyEntity that = (NestedLegacyEntity) o;
|
||||||
|
|
||||||
|
if (legacyEntity != null ? !legacyEntity.equals(that.legacyEntity) : that.legacyEntity != null) return false;
|
||||||
|
return modernEntity != null ? modernEntity.equals(that.modernEntity) : that.modernEntity == null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = legacyEntity != null ? legacyEntity.hashCode() : 0;
|
||||||
|
result = 31 * result + (modernEntity != null ? modernEntity.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NestedLegacyEntity{" +
|
||||||
|
"legacyEntity=" + legacyEntity +
|
||||||
|
", modernEntity=" + modernEntity +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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.factory.puUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class NestedLegacyEntityPk implements Serializable {
|
||||||
|
|
||||||
|
private LegacyEntityPk legacyEntity;
|
||||||
|
|
||||||
|
private int modernEntity;
|
||||||
|
|
||||||
|
public NestedLegacyEntityPk() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyEntityPk getLegacyEntity() {
|
||||||
|
return legacyEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegacyEntity(LegacyEntityPk legacyEntity) {
|
||||||
|
this.legacyEntity = legacyEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getModernEntity() {
|
||||||
|
return modernEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModernEntity(int modernEntity) {
|
||||||
|
this.modernEntity = modernEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
NestedLegacyEntityPk that = (NestedLegacyEntityPk) o;
|
||||||
|
|
||||||
|
if (modernEntity != that.modernEntity) return false;
|
||||||
|
return legacyEntity != null ? legacyEntity.equals(that.legacyEntity) : that.legacyEntity == null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = legacyEntity != null ? legacyEntity.hashCode() : 0;
|
||||||
|
result = 31 * result + modernEntity;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.jpa.internal.PersistenceUnitUtilImpl;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
@ -53,6 +55,9 @@ public class CompositeIdDerivedIdWithIdClassTest extends BaseCoreFunctionalTestC
|
||||||
ShoppingCart transientCart = new ShoppingCart( "cart1" );
|
ShoppingCart transientCart = new ShoppingCart( "cart1" );
|
||||||
transientCart.addLineItem( new LineItem( 0, "description2", transientCart ) );
|
transientCart.addLineItem( new LineItem( 0, "description2", transientCart ) );
|
||||||
|
|
||||||
|
// assertion for HHH-11274 - checking for exception
|
||||||
|
final Object identifier = new PersistenceUnitUtilImpl( sessionFactory() ).getIdentifier( transientCart.getLineItems().get( 0 ) );
|
||||||
|
|
||||||
// merge ID with transient many-to-one
|
// merge ID with transient many-to-one
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
s.getTransaction().begin();
|
s.getTransaction().begin();
|
||||||
|
@ -63,6 +68,8 @@ public class CompositeIdDerivedIdWithIdClassTest extends BaseCoreFunctionalTestC
|
||||||
s = openSession();
|
s = openSession();
|
||||||
s.getTransaction().begin();
|
s.getTransaction().begin();
|
||||||
ShoppingCart updatedCart = s.get( ShoppingCart.class, "cart1" );
|
ShoppingCart updatedCart = s.get( ShoppingCart.class, "cart1" );
|
||||||
|
// assertion for HHH-11274 - checking for exception
|
||||||
|
new PersistenceUnitUtilImpl( sessionFactory() ).getIdentifier( transientCart.getLineItems().get( 0 ) );
|
||||||
assertEquals( 1, updatedCart.getLineItems().size() );
|
assertEquals( 1, updatedCart.getLineItems().size() );
|
||||||
assertEquals( "description2", updatedCart.getLineItems().get( 0 ).getDescription() );
|
assertEquals( "description2", updatedCart.getLineItems().get( 0 ).getDescription() );
|
||||||
s.getTransaction().commit();
|
s.getTransaction().commit();
|
||||||
|
|
Loading…
Reference in New Issue