Turns out this issue may be a duplicate of a known issue, taking this over to the dev list.

 

org/hibernate/test/annotations/cid/CompositeIdIdentityTest.java:

     7  package org.hibernate.test.annotations.cid;

    48  @RequiresDialectFeature(DialectChecks.SupportsIdentityColumns.class)

    49  @TestForIssue( jiraKey = "HHH-9662" )

    50  public class CompositeIdIdentityTest extends BaseCoreFunctionalTestCase {

    51

    52          @Test

    53          @FailureExpected( jiraKey = "HHH-9662" )

    54          public void testCompositePkWithIdentity() throws Exception {

    55                  doInHibernate( this::sessionFactory, session -> {

    56                          Animal animal = new Animal();

    57                          animal.setSubId( 123L );

    58                          session.persist(animal);

    59                  } );

    60          }

    61

    70          @Entity

    71          @Table(name = "animal")

    72          @IdClass(IdWithSubId.class)

    73          public static class Animal {

    74

    75                  @Id

    76                  @GeneratedValue(strategy = GenerationType.IDENTITY)

    77                  private Long id;

    78

    79                  @Id

    80                  @Column(name = "sub_id")

    81                  private Long subId;

    82

 

 

From: Jason Pyeron [mailto:jpyeron@pdinc.us]
Sent: Tuesday, April 21, 2020 1:32 AM
To: 'hibernate-users@lists.jboss.org' <hibernate-users@lists.jboss.org>
Subject: HHH-6044 and partial identifier generation - No part of a composite identifier may be null HibernateException

 

[note this is an issue with sequences too]

 

Quoting https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers-composite-nonaggregated

With non-aggregated composite identifiers, Hibernate also supports "partial" generation of the composite values.

Example 135. @IdClass with partial identifier generation using @GeneratedValue

 

I seem to be having the same issues as https://hibernate.atlassian.net/browse/HHH-6044

 

I have existing tables / Entities (simplified):

 

CREATE TABLE [cresaptown].[saar](

       [id] [bigint] IDENTITY(1,1) NOT NULL primary key

);

 

@Entity

@Table(schema = "cresaptown", name = "saar")

public class SystemAccessAuthorizationRequest

{

    @Id

    @GeneratedValue

    Long id;

}

 

CREATE TABLE [cresaptown].[signature](

       [rid] [bigint] IDENTITY(1,1) NOT NULL,

       [sid] [bigint] NOT NULL,

       PRIMARY KEY ([rid],[sid]),

       FOREIGN KEY([rid]) REFERENCES [cresaptown].[saar] ([id])

);

 

@Entity

@Table(schema = "cresaptown", name = "signature")

@IdClass(Signature.ID.class)

public class Signature

{

    @Id

    @Column(name = "sid")

    @GeneratedValue

    Long sid;

 

    @Id

    @JoinColumn(name = "rid")

    @ManyToOne

    SystemAccessAuthorizationRequest rid;

 

    public static class ID implements Serializable

    {

        Long sid;

        Long rid;

    }

}

 

A code fragment

 

            em.getTransaction().begin();

            SystemAccessAuthorizationRequest saar = new SystemAccessAuthorizationRequest();

            em.persist(saar);

            Signature sig = new Signature();

            sig.setRid(saar);

            em.persist(sig);

            em.getTransaction().commit();

 

gives this exception, but if I disable the null check in AbstractEntityTuplizer.getIdentifier, I get the same issue as in HHH-6044

 

javax.persistence.PersistenceException: org.hibernate.HibernateException: No part of a composite identifier may be null

     at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)

     at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)

     at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)

     at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:716)

     at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:696)

     at x.Testclass.x(Testclass.java:38)

     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

     at java.lang.reflect.Method.invoke(Unknown Source)

     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)

     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)

     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

     at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)

     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)

     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)

     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)

     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)

     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

Caused by: org.hibernate.HibernateException: No part of a composite identifier may be null

     at org.hibernate.tuple.entity.AbstractEntityTuplizer$IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:365)

     at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:219)

     at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5119)

     at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4819)

     at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:294)

     at org.hibernate.event.internal.EntityState.getEntityState(EntityState.java:59)

     at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:95)

     at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)

     at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)

     at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:710)

     ... 25 more