Unable to release :(
by Steve Ebersole
I ran the 6.0 Alpha5 release. All the tasks completed fine except I was
not able to upload the "dist" to Sourceforge nor the docs to JBoss. All
artifacts are pushed to BinTray.
4 years, 7 months
Re: [hibernate-dev] run a single unit test speed up?
by Jason Pyeron
I got it down to BUILD SUCCESSFUL in 2m 32s
27 actionable tasks: 5 executed, 22 up-to-date
By using
./gradlew :hibernate-core:test --tests org.hibernate.test.annotations.cid.CompositeIdFkGeneratedValueIdentityTest
Package___________________________ Tests Duration Success rate
org.hibernate.test.annotations.cid 1____ 0.586s__ 100%
For an approximate 250x slow down compared to the test execution, sigh.
> -----Original Message-----
> From: hibernate-dev-bounces(a)lists.jboss.org <hibernate-dev-bounces(a)lists.jboss.org> On Behalf Of Jason
> Pyeron
> Sent: Wednesday, April 22, 2020 4:48 PM
> To: 'Hibernate Dev' <hibernate-dev(a)lists.jboss.org>
> Subject: [hibernate-dev] run a single unit test???? do I really have to manually put -x for every task
> I do not want?
>
> Does anyone know how to get a single unit test to run without building a battleship too? Tried in
> eclipse too.
>
> ./gradlew test --tests org.hibernate.test.annotations.cid.CompositeIdFkGeneratedValueIdentityTest
>
> ... 5 minutes later ...
>
> FAILURE: Build failed with an exception.
>
> * What went wrong:
> Execution failed for task ':documentation:test'.
> > No tests found for given includes:
> [org.hibernate.test.annotations.cid.CompositeIdFkGeneratedValueIdentityTest](--tests filter)
>
> * Try:
> Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log
> output. Run with --scan to get full insights.
>
> * Get more help at https://help.gradle.org
>
> Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
> Use '--warning-mode all' to show the individual deprecation warnings.
> See https://docs.gradle.org/4.10.3/userguide/command_line_interface.html#sec:...
>
> BUILD FAILED in 4m 38s
> 36 actionable tasks: 35 executed, 1 up-to-date
>
> --
> Jason Pyeron | Architect
> PD Inc |
> 10 w 24th St |
> Baltimore, MD |
>
> .mil: jason.j.pyeron.ctr(a)mail.mil
> .com: jpyeron(a)pdinc.us
> tel : 202-741-9397
>
>
>
>
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
4 years, 7 months
Trying to understand the significance and use of the sequence methods in Dialect
by Jason Pyeron
Other than the javadocs, are these documented anywhere?
* public String getSequenceNextValString(String sequenceName)
* public String getSelectSequenceNextValString(String sequenceName)
I have been following their usage throughout the codebase, but it is not easy.
Is getSequenceNextValString only used in place of single values? E.g. INSERT INTO NEW_USER VALUES (SEQ_USER.NEXTVAL, 'Adams', 'John') ? Or are there other uses?
Is getSelectSequenceNextValString only used to get the "batch" for Hibernate's future issuance of ids?
The reason I am asking is we would like to leverage the MS SQL Server's sp_sequence_get_range . By using the approach of using the stored procedure for Hibernate's allocation and otherwise using an increment by 1 allows higher efficiency with the Hibernate based application and prevent breaking legacy access to the table/use of the sequence. This topic was unclearly broached in HHH-10130. Internet research below...
Take the following example:
CREATE SEQUENCE [dbo].[hibernate_sequence2]
AS [bigint]
START WITH 1
INCREMENT BY 1
CACHE 200
;
CREATE TABLE [MyTable2]
(
[ID] [bigint] PRIMARY KEY NOT NULL DEFAULT (NEXT VALUE FOR [dbo].[hibernate_sequence2]),
[Title] [nvarchar](64) NOT NULL
);
insert into MyTable2 (Title) values ('test 1');
insert into MyTable2 (Title) values ('test 2');
insert into MyTable2 (Title) values ('test 3');
insert into MyTable2 (Title) values ('test 4');
select * from MyTable2;
--ID Title
--1 test 1
--2 test 2
--3 test 3
--4 test 4
DECLARE @range_first_value_output sql_variant ;
declare @range_size int=50+1;
DECLARE @sequence_increment sql_variant ;
declare @range_last_value sql_variant;
EXEC sys.sp_sequence_get_range
@sequence_name = N'[dbo].[hibernate_sequence2]'
, @range_size = @range_size
, @range_first_value = @range_first_value_output OUTPUT
, @sequence_increment = @sequence_increment OUTPUT
, @range_last_value = @range_last_value OUTPUT ;
SELECT @range_first_value_output AS FirstNumber, @sequence_increment as sequence_increment, @range_last_value as range_last_value ;
--FirstNumber sequence_increment range_last_value
-- 5 1 55
insert into MyTable2 (Title) values ('test 5');
select * from MyTable2;
--ID Title
--1 test 1
--2 test 2
--3 test 3
--4 test 4
--56 test 5
I know there are issues of "knowing" the @SequenceGenerator(allocationSize), but I will assume a fixed 50 for now.
Internet research and other useless links...
1: Not hibernate, but same goal - https://groups.google.com/forum/#!topic/ebean/wG6VyVfEMQk
2: Not helpful - https://stackoverflow.com/questions/17780394/hibernate-identity-vs-sequen...
3: Closest Hibernate Hit - https://hibernate.atlassian.net/browse/HHH-10130
4: My google searches - https://www.google.com/search?safe=off&q=%22sp_sequence_get_range%22+hibe... and https://www.google.com/search?safe=off&q=%22sp_sequence_get_range%22+jpa
5: An interesting discussion, but not applicable - https://hibernate.atlassian.net/browse/HHH-10560
6: Sequences Added to SQL Server Dialect - https://hibernate.atlassian.net/browse/HHH-8440
7: My JIRA search - https://hibernate.atlassian.net/browse/HHH-6950?jql=(text%20~%20sequence%...
-Jason
--
Jason Pyeron | Architect
PD Inc |
10 w 24th St |
Baltimore, MD |
.mil: jason.j.pyeron.ctr(a)mail.mil
.com: jpyeron(a)pdinc.us
tel : 202-741-9397
4 years, 7 months
Re: [hibernate-dev] [hibernate/hibernate-orm] HHH-10956 test cases and fix (#3368)
by Jason Pyeron
Github has been down for a while, so moving to mailing list.
> Hi @pdinc-oss ,
>
> the issue it is how you define the `IdClass`
>
> for such a case
>
> ```
> @Entity
> @IdClass(PK.class)
> public static class NodeS {
>
> @Id
> @GeneratedValue(strategy = GenerationType.SEQUENCE)
> private Long nid;
>
> @Id
> @ManyToOne
> private HeadS hid;
> ...
> }
> ```
>
> the class has to be
>
> ```
> class PK implements Serializable {
>
> private Long nid;
>
> private HeadS hid;
>
> public PK(Long nid, HeadS hid) {
> this.nid = nid;
> this.hid = hid;
> }
> ...
> }
> ```
JPA 2 spec 2.4.1.3 Examples of Derived Identities,
Case (a): The dependent entity uses IdClass to represent a composite key:
```
public class DependentId {
String name; // matches name of @Id attribute
long emp; // matches name of @Id attribute and type of Employee PK
}
@Entity
@IdClass(DependentId.class)
public class Dependent {
@Id String name;
// id attribute mapped by join column default
@Id @ManyToOne Employee emp;
...
}
```
HeadS is the Entity type and its Id type is Long.
I backed out the changes to SimpleValue.java/AbstractEntityTuplizer.java and changed the IdClasses to match and it does pass the tests in Hibernate.
But when testing 2.4.1.3, case a without the patch the following tests fails:
- testCompositePkWithIdentityAndFKByAuto: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKByAuto2: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKBySequence: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKBySequence2: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKByTable: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKByTable2: No part of a composite identifier may be null
These tests are expected to fail / ignored:
- testCompositePkWithIdentityAndFKByIdentity: No part of a composite identifier may be null
- testCompositePkWithIdentityAndFKByIdentity2: skipped
-Jason
—
You are receiving this because you were mentioned.
Reply to this email directly, https://github.com/hibernate/hibernate-orm/pull/3368#issuecomment-618352419, or https://github.com/notifications/unsubscribe-auth/AAQUDIQWBZ5E4INWC5ELIZ3....
4 years, 7 months
HHH-10956 fixed, pull request pending
by Jason Pyeron
This fix addresses partially-generated composite id failure introduced with HHH-4848.
The pull request is at https://github.com/hibernate/hibernate-orm/pull/3368 .
Please review and can this be backported to 5.2? We have cherry picked it and applied it to 5.2.18.Final on JDK8 with SQLServer2012Dialect and are tracking its performance (our bug 2092).
HHH-9662 will continue to need some work for SQL Server, but otherwise seems to work nicely. I have opened HHH-13970 as a sub-task for it so it can be treated as a known issue.
The unit tests for this issue have some issues in the hibernate provided unit testing framework and I have opened a ticket (HHH-13971) for those issues. It is likely a very low priority item.
v/r,
Jason Pyeron
$ git logg -5
* 4138772878 2020-04-22 (HEAD -> HHH-10956) HHH-10956 put one line if in {} jpyeron(a)pdinc.us
* 683e00a399 2020-04-22 HHH-10956 added more complext tests with self referential FK jpyeron(a)pdinc.us
* 9653fee5b7 2020-04-22 HHH-10956 fixed failed insertion with IdClass with partial identifier generation jpyeron(a)pdinc.us
* eca5c5a884 2020-04-22 HHH-10956 created test cases IdClass with partial identifier generatiod, all marked @FailureExpected jpyeron(a)pdinc.us
* 5104c4b7f3 2020-03-26 (tag: 5.4.13) 5.4.13 gbadner(a)redhat.com
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
index 8844440831..d9f8b65ec9 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
@@ -264,6 +264,17 @@ public class SimpleValue implements KeyValue {
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
public IdentifierGenerator createIdentifierGenerator(
IdentifierGeneratorFactory identifierGeneratorFactory,
diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
index 3d137219d0..53fa2d9d12 100644
--- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
+++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
@@ -26,8 +26,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.Assigned;
import org.hibernate.loader.PropertyPath;
import org.hibernate.mapping.Component;
+import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.property.access.spi.Getter;
@@ -168,11 +170,13 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
}
else {
identifierMapperType = (CompositeType) mapper.getType();
+ KeyValue identifier = mappingInfo.getIdentifier();
mappedIdentifierValueMarshaller = buildMappedIdentifierValueMarshaller(
getEntityName(),
getFactory(),
(ComponentType) entityMetamodel.getIdentifierProperty().getType(),
- (ComponentType) identifierMapperType
+ (ComponentType) identifierMapperType,
+ identifier
);
}
}
@@ -274,7 +278,8 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
String entityName,
SessionFactoryImplementor sessionFactory,
ComponentType mappedIdClassComponentType,
- ComponentType virtualIdComponent) {
+ ComponentType virtualIdComponent,
+ KeyValue 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
// in the entity and in the identifier value. The incoming value should
@@ -302,7 +307,8 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
entityName,
sessionFactory,
virtualIdComponent,
- mappedIdClassComponentType
+ mappedIdClassComponentType,
+ identifier
);
}
@@ -341,28 +347,42 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
private final SessionFactoryImplementor sessionFactory;
private final ComponentType virtualIdComponent;
private final ComponentType mappedIdentifierType;
+ private final KeyValue identifier;
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(
String entityName,
SessionFactoryImplementor sessionFactory,
ComponentType virtualIdComponent,
- ComponentType mappedIdentifierType) {
+ ComponentType mappedIdentifierType,
+ KeyValue identifier) {
this.sessionFactory = sessionFactory;
this.entityName = entityName;
this.virtualIdComponent = virtualIdComponent;
this.mappedIdentifierType = mappedIdentifierType;
+ this.identifier = identifier;
}
@Override
public Object getIdentifier(Object entity, EntityMode entityMode, SharedSessionContractImplementor session) {
final Object id = mappedIdentifierType.instantiate( entityMode );
final Object[] propertyValues = virtualIdComponent.getPropertyValues( entity, entityMode );
+ final String[] names = virtualIdComponent.getPropertyNames();
final Type[] subTypes = virtualIdComponent.getSubtypes();
final Type[] copierSubTypes = mappedIdentifierType.getSubtypes();
final int length = subTypes.length;
for ( int i = 0; i < length; i++ ) {
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
if ( subTypes[i].isAssociationType() && !copierSubTypes[i].isAssociationType() ) {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/cid/CompositeIdFkGeneratedValueIdentityTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/cid/CompositeIdFkGeneratedValueIdentityTest.java
new file mode 100644
index 0000000000..3ec3ffcb94
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/cid/CompositeIdFkGeneratedValueIdentityTest.java
@@ -0,0 +1,676 @@
+/*
+ * 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.test.annotations.cid;
+
+import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.ManyToOne;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.SQLServer2012Dialect;
+import org.hibernate.testing.FailureExpected;
+import org.hibernate.testing.TestForIssue;
+import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This tests the design demonstrated in the <a href=
+ * 'https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_...'>user
+ * guide</a>, example "@{@link IdClass} with partial identifier generation using @{@link GeneratedValue}". The
+ * getters and setters have been omitted for clarity of the code. A separate test has been made for
+ * {@link GenerationType#SEQUENCE}, {@link GenerationType#IDENTITY}, {@link GenerationType#TABLE}, and
+ * {@link GenerationType#AUTO} since there are known complications with some {@link Dialect}s (e.g.
+ * {@link SQLServer2012Dialect}) and the {@link GenerationType#IDENTITY}
+ *
+ * @author Jason Pyeron <support(a)pdinc.us>
+ * @see <a href='https://hibernate.atlassian.net/browse/HHH-10956'>HHH-10956</a> Persisting partially-generated
+ * composite Ids fails
+ * @see <a href='https://hibernate.atlassian.net/browse/HHH-9662'>HHH-9662</a> a related and blocking bug for
+ * {@link GenerationType#IDENTITY}
+ * @see <a href='https://hibernate.atlassian.net/browse/HHH-4848'>HHH-4848</a> introduced the regression
+ */
+@TestForIssue(jiraKey = "HHH-10956")
+public class CompositeIdFkGeneratedValueIdentityTest extends BaseCoreFunctionalTestCase {
+
+ @Test
+ public void testCompositePkWithIdentityAndFKBySequence() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadS head = new HeadS();
+ head.name = "Head by Sequence";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ NodeS node = new NodeS();
+ node.hid = head;
+ node.name = "Node by Sequence";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid );
+ } );
+ }
+
+ @Test
+ @FailureExpected(jiraKey = "HHH-9662", message = "Could not set field value [POST_INSERT_INDICATOR]")
+ public void testCompositePkWithIdentityAndFKByIdentity() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadI head = new HeadI();
+ head.name = "Head by Identity";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ NodeI node = new NodeI();
+ node.hid = head;
+ node.name = "Node by Identity";
+ try {
+ session.persist( node );
+ }
+ catch (Error | RuntimeException e) {
+ // expected failure...
+ e.printStackTrace( System.out );
+ throw e;
+ }
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid );
+ } );
+ }
+
+ @Test
+ public void testCompositePkWithIdentityAndFKByTable() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadT head = new HeadT();
+ head.name = "Head by Table";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ NodeT node = new NodeT();
+ node.hid = head;
+ node.name = "Node by Table";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid );
+ } );
+ }
+
+ @Test
+ public void testCompositePkWithIdentityAndFKByAuto() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadA head = new HeadA();
+ head.name = "Head by Auto";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ NodeA node = new NodeA();
+ node.hid = head;
+ node.name = "Node by Auto";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid );
+ } );
+ }
+
+ @Test
+ public void testCompositePkWithIdentityAndFKBySequence2() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadS head = new HeadS();
+ head.name = "Head by Sequence";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ ComplexNodeS node = new ComplexNodeS();
+ node.hid = head;
+ node.name = "Node by Sequence";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid + " with parent="
+ + ( node.parent == null ? null : node.parent.nid + ":" + node.parent.hid.hid ) );
+
+ ComplexNodeS node2 = new ComplexNodeS();
+ node2.hid = head;
+ node2.name = "Node 2 by Sequence";
+ node2.parent = node;
+ session.persist( node2 );
+ System.out.println( "VALUE =>" + node2.name + "=" + node2.nid + ":" + node2.hid.hid + " with parent="
+ + ( node2.parent == null ? null : node2.parent.nid + ":" + node2.parent.hid.hid ) );
+ } );
+ }
+
+ @Test
+ @Ignore("HHH-13971 - unit test DB is using call next value for hibernate_sequence when it should be Identity insert")
+ @FailureExpected(jiraKey = "HHH-9662", message = "Could not set field value [POST_INSERT_INDICATOR]")
+ public void testCompositePkWithIdentityAndFKByIdentity2() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadI head = new HeadI();
+ head.name = "Head by Identity";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ ComplexNodeI node = new ComplexNodeI();
+ node.hid = head;
+ node.name = "Node by Identity";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid + " with parent="
+ + ( node.parent == null ? null : node.parent.nid + ":" + node.parent.hid.hid ) );
+
+ ComplexNodeI node2 = new ComplexNodeI();
+ node2.hid = head;
+ node2.name = "Node 2 by Identity";
+ node2.parent = node;
+ session.persist( node2 );
+ System.out.println( "VALUE =>" + node2.name + "=" + node2.nid + ":" + node2.hid.hid + " with parent="
+ + ( node2.parent == null ? null : node2.parent.nid + ":" + node2.parent.hid.hid ) );
+ } );
+ }
+
+ @Test
+ public void testCompositePkWithIdentityAndFKByTable2() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadT head = new HeadT();
+ head.name = "Head by Table";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ ComplexNodeT node = new ComplexNodeT();
+ node.hid = head;
+ node.name = "Node by Table";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid + " with parent="
+ + ( node.parent == null ? null : node.parent.nid + ":" + node.parent.hid.hid ) );
+
+ ComplexNodeT node2 = new ComplexNodeT();
+ node2.hid = head;
+ node2.name = "Node 2 by Table";
+ node2.parent = node;
+ session.persist( node2 );
+ System.out.println( "VALUE =>" + node2.name + "=" + node2.nid + ":" + node2.hid.hid + " with parent="
+ + ( node2.parent == null ? null : node2.parent.nid + ":" + node2.parent.hid.hid ) );
+ } );
+ }
+
+ @Test
+ public void testCompositePkWithIdentityAndFKByAuto2() throws Exception {
+ doInHibernate( this::sessionFactory, session -> {
+ HeadA head = new HeadA();
+ head.name = "Head by Auto";
+ session.persist( head );
+ System.out.println( "VALUE =>" + head.name + "=" + head.hid );
+
+ ComplexNodeA node = new ComplexNodeA();
+ node.hid = head;
+ node.name = "Node by Auto";
+ session.persist( node );
+ System.out.println( "VALUE =>" + node.name + "=" + node.nid + ":" + node.hid.hid + " with parent="
+ + ( node.parent == null ? null : node.parent.nid + ":" + node.parent.hid.hid ) );
+
+ ComplexNodeA node2 = new ComplexNodeA();
+ node2.hid = head;
+ node2.name = "Node 2 by Auto";
+ node2.parent = node;
+ session.persist( node2 );
+ System.out.println( "VALUE =>" + node2.name + "=" + node2.nid + ":" + node2.hid.hid + " with parent="
+ + ( node2.parent == null ? null : node2.parent.nid + ":" + node2.parent.hid.hid ) );
+ } );
+ }
+
+ @Override
+ protected Class<?>[] getAnnotatedClasses() {
+ return new Class[]{
+ HeadS.class,
+ NodeS.class,
+ HeadA.class,
+ NodeA.class,
+ HeadI.class,
+ NodeI.class,
+ HeadT.class,
+ NodeT.class,
+ ComplexNodeS.class,
+ ComplexNodeI.class,
+ ComplexNodeT.class,
+ ComplexNodeA.class,
+ };
+ }
+
+ @Entity
+ public static class HeadS {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long hid;
+
+ private String name;
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.NodeS.PK.class)
+ public static class NodeS {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadS hid;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ public static class HeadI {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long hid;
+
+ private String name;
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.NodeI.PK.class)
+ public static class NodeI {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadI hid;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ public static class HeadA {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long hid;
+
+ private String name;
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.NodeA.PK.class)
+ public static class NodeA {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadA hid;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ public static class HeadT {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.TABLE)
+ private Long hid;
+
+ private String name;
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.NodeT.PK.class)
+ public static class NodeT {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.TABLE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadT hid;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.ComplexNodeS.PK.class)
+ public static class ComplexNodeS {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadS hid;
+
+ @ManyToOne
+ private ComplexNodeS parent;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.ComplexNodeI.PK.class)
+ public static class ComplexNodeI {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadI hid;
+
+ @ManyToOne
+ private ComplexNodeI parent;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.ComplexNodeT.PK.class)
+ public static class ComplexNodeT {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadT hid;
+
+ @ManyToOne
+ private ComplexNodeT parent;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+ @Entity
+ @IdClass(CompositeIdFkGeneratedValueIdentityTest.ComplexNodeA.PK.class)
+ public static class ComplexNodeA {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long nid;
+
+ @Id
+ @ManyToOne
+ private HeadA hid;
+
+ @ManyToOne
+ private ComplexNodeA parent;
+
+ private String name;
+
+ public static class PK implements Serializable {
+
+ private Long nid;
+
+ private Long hid;
+
+ public PK(Long nid, Long hid) {
+ this.nid = nid;
+ this.hid = hid;
+ }
+
+ private PK() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ PK pk = (PK) o;
+ return Objects.equals( nid, pk.nid ) && Objects.equals( hid, pk.hid );
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash( nid, hid );
+ }
+ }
+
+ }
+
+}
--
Jason Pyeron | Architect
Contractor |
PD Inc |
10 w 24th St |
Baltimore, MD |
.mil: <mailto:jason.j.pyeron.ctr@mail.mil> jason.j.pyeron.ctr(a)mail.mil
.com: <mailto:jpyeron@pdinc.us> jpyeron(a)pdinc.us
tel : 202-741-9397
4 years, 7 months
run a single unit test???? do I really have to manually put -x for every task I do not want?
by Jason Pyeron
Does anyone know how to get a single unit test to run without building a battleship too? Tried in eclipse too.
./gradlew test --tests org.hibernate.test.annotations.cid.CompositeIdFkGeneratedValueIdentityTest
... 5 minutes later ...
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':documentation:test'.
> No tests found for given includes: [org.hibernate.test.annotations.cid.CompositeIdFkGeneratedValueIdentityTest](--tests filter)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.3/userguide/command_line_interface.html#sec:...
BUILD FAILED in 4m 38s
36 actionable tasks: 35 executed, 1 up-to-date
--
Jason Pyeron | Architect
PD Inc |
10 w 24th St |
Baltimore, MD |
.mil: jason.j.pyeron.ctr(a)mail.mil
.com: jpyeron(a)pdinc.us
tel : 202-741-9397
4 years, 7 months
Re: [hibernate-dev] HHH-6044 / HHH-9662 and partial identifier generation - No part of a composite identifier may be null HibernateException
by Jason Pyeron
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(a)lists.jboss.org' <hibernate-users(a)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_...
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
4 years, 7 months