HHH-10956 fixed failed insertion with IdClass with partial identifier generation
* regression introduced by HHH-4848 * AbstractEntityTuplizer lines 179 and 311 formatting issues, preserved * bug HHH-9662 blocks testing of Identity insertion
This commit is contained in:
parent
77d60e5d6e
commit
87cfe33b5c
|
@ -264,6 +264,17 @@ public class SimpleValue implements KeyValue {
|
||||||
|
|
||||||
private IdentifierGenerator identifierGenerator;
|
private IdentifierGenerator identifierGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cached identifierGenerator.
|
||||||
|
*
|
||||||
|
* @return IdentifierGenerator null if
|
||||||
|
* {@link #createIdentifierGenerator(IdentifierGeneratorFactory, Dialect, String, String, RootClass)} was never
|
||||||
|
* completed.
|
||||||
|
*/
|
||||||
|
public IdentifierGenerator getIdentifierGenerator() {
|
||||||
|
return identifierGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdentifierGenerator createIdentifierGenerator(
|
public IdentifierGenerator createIdentifierGenerator(
|
||||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||||
|
|
|
@ -26,8 +26,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.id.Assigned;
|
import org.hibernate.id.Assigned;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
|
import org.hibernate.mapping.KeyValue;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.SimpleValue;
|
||||||
import org.hibernate.metamodel.spi.MetamodelImplementor;
|
import org.hibernate.metamodel.spi.MetamodelImplementor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
@ -168,11 +170,13 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
identifierMapperType = (CompositeType) mapper.getType();
|
identifierMapperType = (CompositeType) mapper.getType();
|
||||||
|
KeyValue identifier = mappingInfo.getIdentifier();
|
||||||
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
|
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
|
||||||
getEntityName(),
|
getEntityName(),
|
||||||
getFactory(),
|
getFactory(),
|
||||||
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
|
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
|
||||||
(ComponentType) identifierMapperType
|
(ComponentType) identifierMapperType,
|
||||||
|
identifier
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,7 +278,8 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
String entityName,
|
String entityName,
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
ComponentType mappedIdClassComponentType,
|
ComponentType mappedIdClassComponentType,
|
||||||
ComponentType virtualIdComponent) {
|
ComponentType virtualIdComponent,
|
||||||
|
KeyValue identifier) {
|
||||||
// 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
|
||||||
// which is an awful way to say that the identifier is represented differently
|
// which is an awful way to say that the identifier is represented differently
|
||||||
// in the entity and in the identifier value. The incoming value should
|
// in the entity and in the identifier value. The incoming value should
|
||||||
|
@ -302,7 +307,8 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
entityName,
|
entityName,
|
||||||
sessionFactory,
|
sessionFactory,
|
||||||
virtualIdComponent,
|
virtualIdComponent,
|
||||||
mappedIdClassComponentType
|
mappedIdClassComponentType,
|
||||||
|
identifier
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,28 +347,40 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
private final SessionFactoryImplementor sessionFactory;
|
private final SessionFactoryImplementor sessionFactory;
|
||||||
private final ComponentType virtualIdComponent;
|
private final ComponentType virtualIdComponent;
|
||||||
private final ComponentType mappedIdentifierType;
|
private final ComponentType mappedIdentifierType;
|
||||||
|
private final KeyValue identifier;
|
||||||
|
|
||||||
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
|
||||||
String entityName,
|
String entityName,
|
||||||
SessionFactoryImplementor sessionFactory,
|
SessionFactoryImplementor sessionFactory,
|
||||||
ComponentType virtualIdComponent,
|
ComponentType virtualIdComponent,
|
||||||
ComponentType mappedIdentifierType) {
|
ComponentType mappedIdentifierType,
|
||||||
|
KeyValue identifier) {
|
||||||
this.sessionFactory = sessionFactory;
|
this.sessionFactory = sessionFactory;
|
||||||
this.entityName = entityName;
|
this.entityName = entityName;
|
||||||
this.virtualIdComponent = virtualIdComponent;
|
this.virtualIdComponent = virtualIdComponent;
|
||||||
this.mappedIdentifierType = mappedIdentifierType;
|
this.mappedIdentifierType = mappedIdentifierType;
|
||||||
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getIdentifier(Object entity, EntityMode entityMode, SharedSessionContractImplementor session) {
|
public Object getIdentifier(Object entity, EntityMode entityMode, SharedSessionContractImplementor session) {
|
||||||
final Object id = mappedIdentifierType.instantiate( entityMode );
|
final Object id = mappedIdentifierType.instantiate( entityMode );
|
||||||
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
|
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
|
||||||
|
final String[] names = virtualIdComponent.getPropertyNames();
|
||||||
final Type[] subTypes = virtualIdComponent.getSubtypes();
|
final Type[] subTypes = virtualIdComponent.getSubtypes();
|
||||||
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
|
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
|
||||||
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" );
|
try {
|
||||||
|
final String name = names[i];
|
||||||
|
final Property p = ((Component) identifier).getProperty(name);
|
||||||
|
final SimpleValue v = (SimpleValue) p.getValue();
|
||||||
|
if ( v.getIdentifierGenerator() == null ) throw new NullPointerException("No IdentifierGenerator found for property "+name);
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
throw new HibernateException( "No part of a composite identifier may be null", t );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//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() ) {
|
||||||
|
|
|
@ -45,7 +45,6 @@ import org.junit.Test;
|
||||||
public class CompositeIdFkGeneratedValueIdentityTest extends BaseCoreFunctionalTestCase {
|
public class CompositeIdFkGeneratedValueIdentityTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(jiraKey = "HHH-10956", message = "javax.persistence.PersistenceException: org.hibernate.HibernateException: No part of a composite identifier may be null")
|
|
||||||
public void testCompositePkWithIdentityAndFKBySequence() throws Exception {
|
public void testCompositePkWithIdentityAndFKBySequence() throws Exception {
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
HeadS head = new HeadS();
|
HeadS head = new HeadS();
|
||||||
|
@ -75,7 +74,6 @@ public class CompositeIdFkGeneratedValueIdentityTest extends BaseCoreFunctionalT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(jiraKey = "HHH-10956", message = "javax.persistence.PersistenceException: org.hibernate.HibernateException: No part of a composite identifier may be null")
|
|
||||||
public void testCompositePkWithIdentityAndFKByTable() throws Exception {
|
public void testCompositePkWithIdentityAndFKByTable() throws Exception {
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
HeadT head = new HeadT();
|
HeadT head = new HeadT();
|
||||||
|
@ -90,7 +88,6 @@ public class CompositeIdFkGeneratedValueIdentityTest extends BaseCoreFunctionalT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected(jiraKey = "HHH-10956", message = "javax.persistence.PersistenceException: org.hibernate.HibernateException: No part of a composite identifier may be null")
|
|
||||||
public void testCompositePkWithIdentityAndFKByAuto() throws Exception {
|
public void testCompositePkWithIdentityAndFKByAuto() throws Exception {
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
HeadA head = new HeadA();
|
HeadA head = new HeadA();
|
||||||
|
|
Loading…
Reference in New Issue