HHH-14219 Fix duplicated rows of sequence table

if generator is shared by multiple entities
This commit is contained in:
Yanming Zhou 2020-09-18 10:59:28 +08:00 committed by Christian Beikov
parent f136dabe18
commit 6fb52c4fcd
2 changed files with 100 additions and 10 deletions

View File

@ -249,8 +249,10 @@ public class TableStructure implements DatabaseStructure {
);
Table table = namespace.locateTable( logicalQualifiedTableName.getObjectName() );
boolean tableCreated = false;
if ( table == null ) {
table = namespace.createTable( logicalQualifiedTableName.getObjectName(), false );
tableCreated = true;
}
this.tableNameText = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
@ -268,17 +270,19 @@ public class TableStructure implements DatabaseStructure {
this.updateQuery = "update " + tableNameText +
" set " + valueColumnNameText + "= ?" +
" where " + valueColumnNameText + "=?";
if ( tableCreated ) {
ExportableColumn valueColumn = new ExportableColumn(
database,
table,
valueColumnNameText,
LongType.INSTANCE
);
ExportableColumn valueColumn = new ExportableColumn(
database,
table,
valueColumnNameText,
LongType.INSTANCE
);
table.addColumn( valueColumn );
table.addColumn( valueColumn );
table.addInitCommand(
new InitCommand( "insert into " + tableNameText + " values ( " + initialValue + " )" )
);
table.addInitCommand(
new InitCommand( "insert into " + tableNameText + " values ( " + initialValue + " )" )
);
}
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.id.enhanced;
import static org.junit.Assert.assertEquals;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.query.Query;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.CustomRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* {@inheritDoc}
*
* @author Yanming Zhou
*/
@TestForIssue(jiraKey = "HHH-14219")
@RunWith(CustomRunner.class)
@RequiresDialect(MySQLDialect.class)
public class HHH14219 {
private SessionFactory sf;
@Before
public void setup() {
StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder()
.applySetting("hibernate.show_sql", "true").applySetting("hibernate.format_sql", "true")
.applySetting("hibernate.hbm2ddl.auto", "create-drop");
Metadata metadata = new MetadataSources(srb.build()).addAnnotatedClass(BaseEntity.class)
.addAnnotatedClass(Foo.class).addAnnotatedClass(Bar.class).buildMetadata();
sf = metadata.buildSessionFactory();
}
@Test
public void testSequenceTableContainsOnlyOneRow() throws Exception {
try (Session session = sf.openSession()) {
@SuppressWarnings("unchecked")
Query<Number> q = session.createNativeQuery("select count(*) from " + BaseEntity.SHARED_SEQ_NAME);
assertEquals(1, q.uniqueResult().intValue());
}
}
@MappedSuperclass
public static class BaseEntity {
public static final String SHARED_SEQ_NAME = "shared_seq";
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = SHARED_SEQ_NAME)
protected Long id;
}
@Entity
public static class Foo extends BaseEntity {
}
@Entity
public static class Bar extends BaseEntity {
}
}