diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java b/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java index 785e38f25c..bc0bce4be4 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/DelayedPostInsertIdentifier.java @@ -24,6 +24,7 @@ package org.hibernate.action.internal; import java.io.Serializable; +import java.util.concurrent.atomic.AtomicLong; /** * Acts as a stand-in for an entity identifier which is supposed to be @@ -36,9 +37,11 @@ import java.io.Serializable; * the entity instance or returned to the client... * * @author Steve Ebersole + * @author Sanne Grinovero */ -public class DelayedPostInsertIdentifier implements Serializable { - private static long sequence; +public class DelayedPostInsertIdentifier implements Serializable, Comparable { + + private static final AtomicLong sequence = new AtomicLong( 0 ); private final long identifier; @@ -46,12 +49,17 @@ public class DelayedPostInsertIdentifier implements Serializable { * Constructs a DelayedPostInsertIdentifier */ public DelayedPostInsertIdentifier() { - synchronized( DelayedPostInsertIdentifier.class ) { - if ( sequence == Long.MAX_VALUE ) { - sequence = 0; + long value = sequence.incrementAndGet(); + if ( value < 0 ) { + synchronized ( sequence ) { + value = sequence.incrementAndGet(); + if ( value < 0 ) { + sequence.set( 0 ); + value = 0; + } } - this.identifier = sequence++; } + this.identifier = value; } @Override @@ -76,4 +84,17 @@ public class DelayedPostInsertIdentifier implements Serializable { return ""; } + + @Override + public int compareTo(DelayedPostInsertIdentifier that) { + if ( this.identifier < that.identifier ) { + return -1; + } + else if ( this.identifier > that.identifier ) { + return 1; + } + else { + return 0; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java index 2edcd836a2..b6a0f280b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityIdentityInsertAction.java @@ -236,7 +236,7 @@ public final class EntityIdentityInsertAction extends AbstractEntityInsertAction return entityKey != null ? entityKey : delayedEntityKey; } - private static synchronized DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() { + private static DelayedPostInsertIdentifier generateDelayedPostInsertIdentifier() { return new DelayedPostInsertIdentifier(); } diff --git a/hibernate-core/src/test/java/org/hibernate/id/FlushIdGenTest.java b/hibernate-core/src/test/java/org/hibernate/id/FlushIdGenTest.java new file mode 100644 index 0000000000..a31fb37b7f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/id/FlushIdGenTest.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat, Inc. and/or its affiliates or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat, Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +package org.hibernate.id; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; +import org.hibernate.testing.TestForIssue; + +@TestForIssue(jiraKey = "HHH-8611") +public class FlushIdGenTest extends BaseCoreFunctionalTestCase { + + @Test + public void testPersistBeforeTransaction() { + Session session = openSession(); + RootEntity ent1_0 = new RootEntity(); + RootEntity ent1_1 = new RootEntity(); + + session.persist( ent1_0 ); + session.persist( ent1_1 ); + + Transaction tx = session.beginTransaction(); + tx.commit(); //flush + } + + @Override + public Class[] getAnnotatedClasses() { + return new Class[]{ + RootEntity.class, + RelatedEntity.class, + }; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/id/RelatedEntity.java b/hibernate-core/src/test/java/org/hibernate/id/RelatedEntity.java new file mode 100644 index 0000000000..18c9d45b68 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/id/RelatedEntity.java @@ -0,0 +1,56 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat, Inc. and/or its affiliates or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat, Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +package org.hibernate.id; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@javax.persistence.Entity +@javax.persistence.Table(name = "entity2") +public class RelatedEntity { + + @Id + @GeneratedValue + @Column(name = "universalid")// "uid" is a keywork in Oracle + private long uid; + + @javax.persistence.ManyToOne + private RootEntity linkedRoot; + + public long getUid() { + return uid; + } + public void setUid(long uid) { + this.uid = uid; + } + + public void setLinkedRoot(RootEntity linkedRoot) { + this.linkedRoot = linkedRoot; + } + public RootEntity getLinkedRoot() { + return linkedRoot; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/id/RootEntity.java b/hibernate-core/src/test/java/org/hibernate/id/RootEntity.java new file mode 100644 index 0000000000..a53cd7cc60 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/id/RootEntity.java @@ -0,0 +1,59 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat, Inc. and/or its affiliates or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat, Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ + +package org.hibernate.id; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@javax.persistence.Entity +public class RootEntity implements Serializable { + + @Id + @GeneratedValue(strategy= GenerationType.IDENTITY) + @Column(name = "universalid")// "uid" is a keywork in Oracle + private long uid; + + @javax.persistence.OneToMany(mappedBy = "linkedRoot") + private java.util.List linkedEntities = new java.util.ArrayList(); + + public long getUid() { + return uid; + } + public void setUid(long uid) { + this.uid = uid; + } + + public void setLinkedEntities(java.util.List linkedEntities) { + this.linkedEntities = linkedEntities; + } + public java.util.List getLinkedEntities() { + return linkedEntities; + } + +}