Merge remote-tracking branch 'upstream/master' into wip/6.0

This commit is contained in:
Andrea Boriero 2020-10-06 17:36:13 +01:00
commit 93cd8aaf4e
28 changed files with 562 additions and 566 deletions

View File

@ -1102,7 +1102,7 @@ public class ActionQueue {
}
/**
* Check if the this {@link BatchIdentifier} has a parent or grand parent
* Check if this {@link BatchIdentifier} has a parent or grand parent
* matching the given {@link BatchIdentifier} reference.
*
* @param batchIdentifier {@link BatchIdentifier} reference
@ -1269,7 +1269,9 @@ public class ActionQueue {
for ( int i = 0; i < propertyValues.length; i++ ) {
Object value = propertyValues[i];
Type type = propertyTypes[i];
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, value );
if ( value != null ) {
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, value );
}
}
if ( identifierType.isComponentType() ) {

View File

@ -9,6 +9,8 @@ import javax.persistence.TypedQuery;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Before;
import org.junit.Test;
@ -20,6 +22,7 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-14231" )
@RequiresDialectFeature( DialectChecks.SupportsExpectedLobUsagePattern.class )
public class ScrollableResultsObjectArrayCastingTest extends BaseEntityManagerFunctionalTestCase {
@Override
@ -31,7 +34,7 @@ public class ScrollableResultsObjectArrayCastingTest extends BaseEntityManagerFu
public void SetUp() {
doInJPA( this::entityManagerFactory, entityManager -> {
Product product = new Product();
product.binaryValue = "".getBytes();
product.binaryValue = new byte[] { 1, 2, 3 };
entityManager.persist( product );
} );
}

View File

@ -0,0 +1,72 @@
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Nathan Xu
*/
abstract class BaseInsertOrderingTest extends BaseNonConfigCoreFunctionalTestCase {
static class Batch {
String sql;
int size;
Batch(String sql, int size) {
this.sql = sql;
this.size = size;
}
Batch(String sql) {
this( sql, 1 );
}
}
private final PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
}
void verifyContainsBatches(Batch... expectedBatches) {
for ( Batch expectedBatch : expectedBatches ) {
PreparedStatement preparedStatement = connectionProvider.getPreparedStatement( expectedBatch.sql );
try {
verify( preparedStatement, times( expectedBatch.size ) ).addBatch();
verify( preparedStatement, times( 1 ) ).executeBatch();
} catch (SQLException e) {
throw new RuntimeException( e );
}
}
}
void verifyPreparedStatementCount(int expectedBatchCount) {
final int realBatchCount = connectionProvider.getPreparedSQLStatements().size();
assertEquals( String.format( "expected %d batch%s; but found %d batch%s", expectedBatchCount, (expectedBatchCount == 1 ? "" : "es"), realBatchCount, (realBatchCount == 1 ? "" : "es" ) ),
expectedBatchCount, realBatchCount );
}
void clearBatches() {
connectionProvider.clear();
}
}

View File

@ -4,33 +4,32 @@
* 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.engine.spi;
package org.hibernate.test.insertordering;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/*
* @author gajendra.jatav(raaz2.gajendra@gmail.com)
*/
public class BatchSortingTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.ORDER_UPDATES, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "5" );
TestingJtaBootstrap.prepare( settings );
}
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class BatchSortingTest extends BaseInsertOrderingTest {
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[]{
@ -59,7 +58,10 @@ public class BatchSortingTest extends BaseNonConfigCoreFunctionalTestCase {
country.setDistricts( geoDistricts );
session.persist( geoDistrict );
session.persist( nation );
clearBatches();
});
verifyPreparedStatementCount( 4 );
}
@Entity(name = "GeoCountry")

View File

@ -7,7 +7,6 @@
package org.hibernate.test.insertordering;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
@ -21,10 +20,9 @@ import javax.persistence.JoinColumn;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
@ -33,19 +31,14 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
* @author Andrea Boriero
*/
@TestForIssue(jiraKey = "HHH-11216")
public class ElementCollectionTest extends BaseNonConfigCoreFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class ElementCollectionTest extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {Task.class};
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
}
@Test
public void testBatchOrdering() {
doInHibernate( this::sessionFactory, session -> {
@ -56,7 +49,14 @@ public class ElementCollectionTest extends BaseNonConfigCoreFunctionalTestCase {
Task task1 = new Task();
task1.addCategory(Category.A);
session.persist( task1 );
clearBatches();
} );
verifyContainsBatches(
new Batch( "insert into TASK (id) values (?)", 2 ),
new Batch( "insert into TASK_CATEGORY (TASK_ID, categories) values (?, ?)", 2 )
);
}
@Entity

View File

@ -7,9 +7,7 @@
package org.hibernate.test.insertordering;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -20,22 +18,19 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-11634")
public class InsertOrderingDuplicateTest
extends BaseNonConfigCoreFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingDuplicateTest extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
@ -47,19 +42,8 @@ public class InsertOrderingDuplicateTest
};
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
}
@Override
public void releaseResources() {
super.releaseResources();
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
SaleDocumentItem saleDocumentItem = new SaleDocumentItem();
@ -82,9 +66,17 @@ public class InsertOrderingDuplicateTest
session.persist(correction);
saleDocument.setCorerctionsubject( correction);
} );
}
clearBatches();
} );
verifyContainsBatches(
new Batch( "insert into SaleDocumentSummary (sale_number, totalPrice, id) values (?, ?, ?)" ),
new Batch( "insert into Product (description, name, price, quantity, id) values (?, ?, ?, ?, ?)" ),
new Batch( "insert into SaleDocument (ID_SALE_DOCUMENT_CORRECTION, sale_number, totalPrice, id) values (?, ?, ?, ?)", 2 ),
new Batch( "insert into SaleDocumentItem (lp, product_id, quantity, ID_SALE_DOCUMENT, ID_SALE_DOCUMENT_SUMAMRY, id) values (?, ?, ?, ?, ?, ?)" )
);
}
@Entity(name = "Product")
public static class Product {

View File

@ -9,7 +9,6 @@ package org.hibernate.test.insertordering;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -19,10 +18,9 @@ import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
@ -31,18 +29,14 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
* @author Andrea Boriero
*/
@TestForIssue(jiraKey = "HHH-12380")
public class InsertOrderingHasParentTest extends BaseNonConfigCoreFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingHasParentTest extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Author.class, Book.class, Comment.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
}
@Test
public void testInsert() {
@ -55,8 +49,16 @@ public class InsertOrderingHasParentTest extends BaseNonConfigCoreFunctionalTest
author.setBook( book );
session.persist( author );
clearBatches();
} );
verifyContainsBatches(
new Batch( "insert into book_comment (book_comment, id) values (?, ?)", 2 ),
new Batch( "insert into Book (comment_id, id) values (?, ?)" ),
new Batch( "insert into Author (book_id, id) values (?, ?)" ),
new Batch( "insert into Book_book_comment (Book_id, comments_id) values (?, ?)" )
);
}
@Entity(name = "Author")

View File

@ -0,0 +1,84 @@
package org.hibernate.test.insertordering;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/**
* @author Normunds Gavars
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-14227" )
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingReferenceDifferentSubclassTest extends BaseInsertOrderingTest {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
SubclassA.class,
SubclassB.class
};
}
@Test
public void testReferenceDifferentSubclass() {
doInHibernate(this::sessionFactory, session -> {
SubclassA subclassA1 = new SubclassA();
SubclassB subclassB1 = new SubclassB();
SubclassA subclassA2 = new SubclassA();
SubclassB subclassB2 = new SubclassB();
subclassA1.referenceB = subclassB2;
subclassB2.referenceA = subclassA2;
subclassA2.referenceB = subclassB1;
session.save( subclassA1 );
session.save( subclassA2 );
clearBatches();
});
verifyContainsBatches(
new Batch( "insert into SubclassB (referenceA_id, id) values (?, ?)", 2 ),
new Batch( "insert into SubclassA (referenceB_id, id) values (?, ?)", 2 )
);
}
@MappedSuperclass
static class BaseClass {
@Id @GeneratedValue
Long id;
}
@Entity(name = "SubclassA")
static class SubclassA extends BaseClass {
@OneToOne(cascade = CascadeType.ALL)
SubclassB referenceB;
}
@Entity(name = "SubclassB")
static class SubclassB extends BaseClass {
@ManyToOne(fetch = FetchType.LAZY)
SubclassA referenceA;
}
}

View File

@ -19,17 +19,12 @@ import javax.persistence.OneToOne;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.cfg.Environment;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

View File

@ -0,0 +1,131 @@
package org.hibernate.test.insertordering;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.SortNatural;
import org.hibernate.annotations.Where;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/**
* @author Normunds Gavars
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-14227" )
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingSelfReferenceTest extends BaseInsertOrderingTest {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Parameter.class,
InputParameter.class,
OutputParameter.class,
Placeholder.class,
};
}
@Test
public void testReferenceItself() {
doInHibernate( this::sessionFactory, session -> {
Placeholder placeholder = new Placeholder();
session.save( placeholder );
OutputParameter outputParameter1 = new OutputParameter();
OutputParameter childOutputParameter = new OutputParameter();
outputParameter1.children.add( childOutputParameter );
childOutputParameter.parent = outputParameter1;
session.save( outputParameter1 );
Placeholder placeholder2 = new Placeholder();
session.save( placeholder2 );
InputParameter inputParameter = new InputParameter();
session.save( inputParameter );
OutputParameter outputParameter2 = new OutputParameter();
session.save( outputParameter2 );
clearBatches();
} );
verifyContainsBatches(
new Batch( "insert into Placeholder (id) values (?)", 2 ),
new Batch( "insert into Parameter (parent_id, TYPE, id) values (?, 'INPUT', ?)" ),
new Batch( "insert into Parameter (parent_id, TYPE, id) values (?, 'OUTPUT', ?)", 3 )
);
}
@MappedSuperclass
static class AbstractEntity {
@Id
@GeneratedValue
Long id;
}
@Entity(name = "Placeholder")
static class Placeholder extends AbstractEntity {
}
@Entity(name = "Parameter")
@DiscriminatorColumn(name = "TYPE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
static abstract class Parameter extends AbstractEntity {
}
@Entity(name = "InputParameter")
@DiscriminatorValue("INPUT")
static class InputParameter extends Parameter {
@ManyToOne(fetch = FetchType.LAZY)
InputParameter parent;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
@SortNatural
@Where(clause = "TYPE = 'INPUT'")
@Fetch(FetchMode.SUBSELECT)
List<InputParameter> children = new ArrayList<>();
}
@Entity(name = "OutputParameter")
@DiscriminatorValue("OUTPUT")
static class OutputParameter extends Parameter {
@ManyToOne(fetch = FetchType.LAZY)
OutputParameter parent;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
@SortNatural
@Where(clause = "TYPE = 'OUTPUT'")
@Fetch(FetchMode.SUBSELECT)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
List<OutputParameter> children = new ArrayList<>();
}
}

View File

@ -19,7 +19,6 @@ import org.hibernate.cfg.Environment;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

View File

@ -6,11 +6,8 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -20,53 +17,27 @@ import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalManyToMany
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithBidirectionalManyToMany extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person father = new Person();
Person mother = new Person();
@ -87,18 +58,14 @@ public class InsertOrderingWithBidirectionalManyToMany
session.persist( home );
session.persist( office );
connectionProvider.clear();
clearBatches();
} );
assertEquals( 3, connectionProvider.getPreparedStatements().size() );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (ID) values (?)" );
verify( personPreparedStatement, times( 4 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (ID) values (?)", 2 ),
new Batch( "insert into Person (ID) values (?)", 4 ),
new Batch( "insert into Person_Address (persons_ID, addresses_ID) values (?, ?)", 6 )
);
}
@Entity(name = "Address")

View File

@ -6,9 +6,6 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -19,52 +16,27 @@ import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalMapsIdOneToOne
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithBidirectionalMapsIdOneToOne extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class };
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person worker = new Person();
Person homestay = new Person();
@ -79,17 +51,13 @@ public class InsertOrderingWithBidirectionalMapsIdOneToOne
session.persist( home );
session.persist( office );
connectionProvider.clear();
clearBatches();
} );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (address_ID) values (?)" );
verify( personPreparedStatement, times( 2 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (ID) values (?)", 2 ),
new Batch( "insert into Person (address_ID) values (?)", 2 )
);
}
@Entity(name = "Address")

View File

@ -6,11 +6,8 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -21,52 +18,27 @@ import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalOneToMany
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithBidirectionalOneToMany extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class };
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person father = new Person();
Person mother = new Person();
@ -87,17 +59,13 @@ public class InsertOrderingWithBidirectionalOneToMany
session.persist( home );
session.persist( office );
connectionProvider.clear();
clearBatches();
} );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (address_ID, ID) values (?, ?)" );
verify( personPreparedStatement, times( 4 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (ID) values (?)", 2 ),
new Batch( "insert into Person (address_ID, ID) values (?, ?)", 4 )
);
}
@Entity(name = "Address")

View File

@ -8,7 +8,6 @@ package org.hibernate.test.insertordering;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@ -17,19 +16,18 @@ import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static javax.persistence.CascadeType.PERSIST;
import static javax.persistence.GenerationType.SEQUENCE;
import static org.hibernate.cfg.AvailableSettings.ORDER_INSERTS;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_BATCH_SIZE;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
@TestForIssue(jiraKey = "HHH-12074")
public class InsertOrderingWithBidirectionalOneToManyFlushProblem
extends BaseNonConfigCoreFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalOneToManyFlushProblem extends BaseInsertOrderingTest {
@Test
public void testBatchingWithFlush() {
@ -40,12 +38,16 @@ public class InsertOrderingWithBidirectionalOneToManyFlushProblem
session.persist( top1 );
clearBatches();
// InsertActionSorter#sort is invoked during this flush.
//
// input: [top1]
// output: [top1]
session.flush();
verifyContainsBatches( new Batch( "insert into TopEntity (id) values (?)" ) );
MiddleEntity middle1 = new MiddleEntity();
middle1.addBottom( new BottomEntity() );
@ -71,8 +73,16 @@ public class InsertOrderingWithBidirectionalOneToManyFlushProblem
// when the attempt to insert middle2 before top2 is made.
//
// correct ordering is: [top2,middle1,middle2,bottom1,bottom2]
clearBatches();
}
);
verifyContainsBatches(
new Batch( "insert into TopEntity (id) values (?)" ),
new Batch( "insert into MiddleEntity (top_id, id) values (?, ?)", 2 ),
new Batch( "insert into BottomEntity (middle_id, id) values (?, ?)", 2 )
);
}
@Test
@ -89,8 +99,11 @@ public class InsertOrderingWithBidirectionalOneToManyFlushProblem
//
// input: [top1]
// output: [top1]
clearBatches();
session.flush();
verifyContainsBatches( new Batch( "insert into TopEntity (id) values (?)" ) );
MiddleEntity middle1 = new MiddleEntity();
middle1.addBottom( new BottomEntity() );
@ -120,19 +133,21 @@ public class InsertOrderingWithBidirectionalOneToManyFlushProblem
// when the attempt to insert middle2 before top2 is made.
//
// correct ordering is: [top2,middle1,middle2,bottom1,bottom2]
clearBatches();
}
);
verifyContainsBatches(
new Batch( "insert into TopEntity (id) values (?)", 2 ),
new Batch( "insert into MiddleEntity (top_id, id) values (?, ?)", 2 ),
new Batch( "insert into BottomEntity (middle_id, id) values (?, ?)", 2 ),
new Batch( "insert into BottomEntity2 (middle_id, id) values (?, ?)", 2 )
);
}
@Override
protected void addSettings(Map settings) {
settings.put( ORDER_INSERTS, "true" );
settings.put( STATEMENT_BATCH_SIZE, "10" );
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { TopEntity.class, MiddleEntity.class, BottomEntity.class, BottomEntity2.class };
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { TopEntity.class, MiddleEntity.class, BottomEntity.class, BottomEntity2.class };
}
@Entity(name = "BottomEntity")

View File

@ -6,56 +6,36 @@
*/
package org.hibernate.test.insertordering;
import org.hibernate.cfg.Environment;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import javax.persistence.*;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalOneToOne
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithBidirectionalOneToOne extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class };
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person worker = new Person();
Person homestay = new Person();
@ -70,17 +50,13 @@ public class InsertOrderingWithBidirectionalOneToOne
session.persist( home );
session.persist( office );
connectionProvider.clear();
clearBatches();
} );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (address_ID, ID) values (?, ?)" );
verify( personPreparedStatement, times( 2 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (ID) values (?)", 2 ),
new Batch( "insert into Person (address_ID, ID) values (?, ?)", 2 )
);
}
@Entity(name = "Address")

View File

@ -6,27 +6,25 @@
*/
package org.hibernate.test.insertordering;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.hibernate.cfg.AvailableSettings.ORDER_INSERTS;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_BATCH_SIZE;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
@TestForIssue(jiraKey = "HHH-12105")
public class InsertOrderingWithBidirectionalOneToOneFlushProblem
extends BaseNonConfigCoreFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithBidirectionalOneToOneFlushProblem extends BaseInsertOrderingTest {
@Test
public void testInsertSortingWithFlushPersistLeftBeforeRight() {
@ -36,8 +34,11 @@ public class InsertOrderingWithBidirectionalOneToOneFlushProblem
TopEntity top1 = new TopEntity();
session.persist(top1);
clearBatches();
session.flush();
verifyContainsBatches( new Batch( "insert into TopEntity (id) values (?)" ) );
LeftEntity left = new LeftEntity();
RightEntity right = new RightEntity();
TopEntity top2 = new TopEntity();
@ -54,8 +55,16 @@ public class InsertOrderingWithBidirectionalOneToOneFlushProblem
session.persist(left);
session.persist(right);
session.persist(top2);
clearBatches();
}
);
verifyContainsBatches(
new Batch( "insert into TopEntity (id) values (?)" ),
new Batch( "insert into LeftEntity (top_id, id) values (?, ?)" ),
new Batch( "insert into RightEntity (left_id, top_id, id) values (?, ?, ?)" )
);
}
@Test
@ -66,8 +75,11 @@ public class InsertOrderingWithBidirectionalOneToOneFlushProblem
TopEntity top1 = new TopEntity();
session.persist(top1);
clearBatches();
session.flush();
verifyContainsBatches( new Batch( "insert into TopEntity (id) values (?)" ) );
LeftEntity left = new LeftEntity();
RightEntity right = new RightEntity();
TopEntity top2 = new TopEntity();
@ -84,19 +96,21 @@ public class InsertOrderingWithBidirectionalOneToOneFlushProblem
session.persist(right);
session.persist(left);
session.persist(top2);
clearBatches();
}
);
verifyContainsBatches(
new Batch( "insert into TopEntity (id) values (?)" ),
new Batch( "insert into LeftEntity (top_id, id) values (?, ?)" ),
new Batch( "insert into RightEntity (left_id, top_id, id) values (?, ?, ?)" )
);
}
@Override
protected void addSettings(Map settings) {
settings.put( ORDER_INSERTS, "true" );
settings.put( STATEMENT_BATCH_SIZE, "10" );
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[]{
LeftEntity.class, RightEntity.class, TopEntity.class,
};
}

View File

@ -7,7 +7,6 @@
package org.hibernate.test.insertordering;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Access;
import javax.persistence.AccessType;
@ -28,47 +27,24 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithJoinedTableInheritance
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
public class InsertOrderingWithJoinedTableInheritance extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class, SpecialPerson.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class, SpecialPerson.class };
}
@Test
@ -98,10 +74,10 @@ public class InsertOrderingWithJoinedTableInheritance
specialPerson.addAddress( new Address() );
session.persist( specialPerson );
}
connectionProvider.clear();
clearBatches();
} );
assertEquals( 26, connectionProvider.getPreparedStatements().size() );
verifyPreparedStatementCount( 26 );
}
@Override

View File

@ -8,7 +8,6 @@ package org.hibernate.test.insertordering;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -27,31 +26,24 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithJoinedTableMultiLevelInheritance
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
public class InsertOrderingWithJoinedTableMultiLevelInheritance extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Address.class,
Person.class,
SpecialPerson.class,
@ -61,22 +53,6 @@ public class InsertOrderingWithJoinedTableMultiLevelInheritance
};
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
}
@Test
public void testBatchingAmongstSubClasses() {
doInHibernate( this::sessionFactory, session -> {
@ -99,10 +75,10 @@ public class InsertOrderingWithJoinedTableMultiLevelInheritance
specialPerson.addAddress( new Address() );
session.persist( specialPerson );
}
connectionProvider.clear();
clearBatches();
} );
assertEquals( 17, connectionProvider.getPreparedStatements().size() );
verifyPreparedStatementCount( 17 );
}
@Override

View File

@ -6,67 +6,35 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithManyToOne
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithManyToOne extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class };
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person father = new Person();
Person mother = new Person();
@ -89,17 +57,13 @@ public class InsertOrderingWithManyToOne
session.persist( son );
session.persist( daughter );
connectionProvider.clear();
clearBatches();
} );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (address_ID, ID) values (?, ?)" );
verify( personPreparedStatement, times( 4 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (ID) values (?)", 2 ),
new Batch( "insert into Person (address_ID, ID) values (?, ?)", 4 )
);
}
@Entity(name = "Address")

View File

@ -6,72 +6,36 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-11996")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithMultipleManyToOne
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
public class InsertOrderingWithMultipleManyToOne extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Parent.class,
ChildA.class,
ChildB.class,
};
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Parent parent = new Parent();
session.persist(parent);
@ -84,18 +48,16 @@ public class InsertOrderingWithMultipleManyToOne
childB.setParent(parent);
session.persist(childB);
connectionProvider.clear();
clearBatches();
} );
assertEquals( 3, connectionProvider.getPreparedStatements().size() );
/*PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (ID) values (?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (ID) values (?)" );
verify( personPreparedStatement, times( 4 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();*/
verifyPreparedStatementCount( 3 );
/*
Map<String, Integer> expectedBatching = new HashMap<>();
expectedBatching.put( "insert into Address (ID) values (?)", 2 );
expectedBatching.put( "insert into Person (ID) values (?)", 4 );
verifyBatching( expectedBatching );
*/
}
@Entity(name = "Parent")

View File

@ -8,8 +8,6 @@ package org.hibernate.test.insertordering;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
@ -30,25 +28,19 @@ import javax.persistence.SecondaryTable;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/**
* @author Chris Cranford
*/
@TestForIssue(jiraKey = "HHH-11714")
public class InsertOrderingWithSecondaryTable extends BaseEntityManagerFunctionalTestCase {
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
options.put( AvailableSettings.ORDER_INSERTS, Boolean.TRUE );
options.put( AvailableSettings.ORDER_UPDATES, Boolean.TRUE );
}
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithSecondaryTable extends BaseInsertOrderingTest {
@Override
protected Class<?>[] getAnnotatedClasses() {
@ -63,7 +55,7 @@ public class InsertOrderingWithSecondaryTable extends BaseEntityManagerFunctiona
@Test
public void testInheritanceWithSecondaryTable() {
doInJPA( this::entityManagerFactory, entityManager -> {
doInHibernate( this::sessionFactory, session -> {
final TopLevelEntity top = new TopLevelEntity();
final GeographicArea area1 = new GeographicArea();
@ -79,9 +71,18 @@ public class InsertOrderingWithSecondaryTable extends BaseEntityManagerFunctiona
area2.setShape( circle );
top.getGeographicAreas().add( area2 );
entityManager.persist( top );
entityManager.flush();
session.save( top );
clearBatches();
} );
verifyContainsBatches(
new Batch( "insert into TOP_LEVEL (id) values (?)" ),
new Batch( "insert into SHAPE (SHAPE_TYPE, SHAPE_ID) values ('POLYGON', ?)" ),
new Batch( "insert into SHAPE (SHAPE_TYPE, SHAPE_ID) values ('CIRCLE', ?)" ),
new Batch( "insert into SHAPE_CIRCLE (centre, SHAPE_ID) values (?, ?)" ),
new Batch( "insert into GEOGRAPHIC_AREA (SHAPE_ID, TOP_LEVEL_ID, id) values (?, ?, ?)", 2 )
);
}
@Entity

View File

@ -7,7 +7,6 @@
package org.hibernate.test.insertordering;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Access;
import javax.persistence.AccessType;
@ -28,47 +27,24 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithSingleTableInheritance
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
public class InsertOrderingWithSingleTableInheritance extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class, SpecialPerson.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class, SpecialPerson.class };
}
@Test
@ -99,10 +75,10 @@ public class InsertOrderingWithSingleTableInheritance
specialPerson.addAddress( new Address() );
session.persist( specialPerson );
}
connectionProvider.clear();
clearBatches();
} );
assertEquals( 3, connectionProvider.getPreparedStatements().size() );
verifyPreparedStatementCount( 3 );
}
@Override

View File

@ -7,7 +7,6 @@
package org.hibernate.test.insertordering;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Access;
import javax.persistence.AccessType;
@ -28,47 +27,24 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithTablePerClassInheritance
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
public class InsertOrderingWithTablePerClassInheritance extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class, SpecialPerson.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class, SpecialPerson.class };
}
@Test
@ -99,10 +75,10 @@ public class InsertOrderingWithTablePerClassInheritance
specialPerson.addAddress( new Address() );
session.persist( specialPerson );
}
connectionProvider.clear();
clearBatches();
} );
assertEquals( 3, connectionProvider.getPreparedStatements().size() );
verifyPreparedStatementCount( 3 );
}
@Override

View File

@ -6,9 +6,6 @@
*/
package org.hibernate.test.insertordering;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -18,52 +15,27 @@ import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-9864")
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithUnidirectionalOneToOne
extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider( true, false );
public class InsertOrderingWithUnidirectionalOneToOne extends BaseInsertOrderingTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Address.class, Person.class };
}
@Override
protected void addSettings(Map settings) {
settings.put( Environment.ORDER_INSERTS, "true" );
settings.put( Environment.STATEMENT_BATCH_SIZE, "10" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider
);
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Address.class, Person.class };
}
@Test
public void testBatching() throws SQLException {
public void testBatching() {
doInHibernate( this::sessionFactory, session -> {
Person worker = new Person();
Person homestay = new Person();
@ -78,17 +50,13 @@ public class InsertOrderingWithUnidirectionalOneToOne
session.persist( home );
session.persist( office );
connectionProvider.clear();
clearBatches();
} );
PreparedStatement addressPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Address (person_ID, ID) values (?, ?)" );
verify( addressPreparedStatement, times( 2 ) ).addBatch();
verify( addressPreparedStatement, times( 1 ) ).executeBatch();
PreparedStatement personPreparedStatement = connectionProvider.getPreparedStatement(
"insert into Person (ID) values (?)" );
verify( personPreparedStatement, times( 2 ) ).addBatch();
verify( personPreparedStatement, times( 1 ) ).executeBatch();
verifyContainsBatches(
new Batch( "insert into Address (person_ID, ID) values (?, ?)", 2 ),
new Batch( "insert into Person (ID) values (?)", 2 )
);
}
@Entity(name = "Address")

View File

@ -7,8 +7,6 @@
package org.hibernate.test.insertordering;
import java.io.Serializable;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
@ -18,20 +16,20 @@ import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Query;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Chris Cranford
*/
@TestForIssue(jiraKey = "HHH-12569")
public class InsertOrderingWithUnidirectionalOneToOneJoinColumn extends BaseEntityManagerFunctionalTestCase {
@RequiresDialectFeature(DialectChecks.SupportsJdbcDriverProxying.class)
public class InsertOrderingWithUnidirectionalOneToOneJoinColumn extends BaseInsertOrderingTest {
@Embeddable
public static class PersonAddressId implements Serializable {
@Column(name = "id")
@ -90,30 +88,31 @@ public class InsertOrderingWithUnidirectionalOneToOneJoinColumn extends BaseEnti
return new Class<?>[] { Person.class, Address.class };
}
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
options.put( AvailableSettings.ORDER_INSERTS, "true" );
}
@Test
public void testBatchingWithEmbeddableId() {
doInJPA( this::entityManagerFactory, entityManager -> {
doInHibernate( this::sessionFactory, session -> {
final PersonAddressId id = new PersonAddressId();
id.setId( 1 );
Person person = new Person();
person.setId( id );
entityManager.persist( person );
session.persist( person );
Address address = new Address();
address.setId( id );
address.setPerson( person );
entityManager.persist( address );
session.persist( address );
clearBatches();
} );
doInJPA( this::entityManagerFactory, entityManager -> {
Query query = entityManager.createQuery( "FROM Person" );
verifyContainsBatches(
new Batch( "insert into Person (id) values (?)" ),
new Batch( "insert into Address (id) values (?)" )
);
doInHibernate( this::sessionFactory, session -> {
Query query = session.createQuery( "FROM Person" );
assertEquals( 1, query.getResultList().size() );
} );
}

View File

@ -157,11 +157,11 @@ public class PreparedStatementSpyConnectionProvider extends ConnectionProviderDe
List<PreparedStatement> preparedStatements = getPreparedStatements( sql );
if ( preparedStatements.isEmpty() ) {
throw new IllegalArgumentException(
"There is no PreparedStatement for this SQL statement " + sql );
"There is no PreparedStatement for this SQL statement: " + sql );
}
else if ( preparedStatements.size() > 1 ) {
throw new IllegalArgumentException( "There are " + preparedStatements
.size() + " PreparedStatements for this SQL statement " + sql );
.size() + " PreparedStatements for this SQL statement: " + sql );
}
return preparedStatements.get( 0 );
}

View File

@ -300,8 +300,6 @@ task changeLogFile( dependsOn: [releaseChecks] ) {
}
}
task addVersionCommit( dependsOn: [changeLogFile] ) {
group = "Release"
description = "Adds a commit for the released version and push the changes to github"
@ -414,15 +412,14 @@ class ChangeLogFile {
}
def apiString = "https://hibernate.atlassian.net/rest/api/2/search/?jql=project=HHH%20AND%20fixVersion=${restReleaseVersion}%20order%20by%20issuetype%20ASC"
def apiUrl = new URL( apiString )
def releseNotes = new JsonSlurper().parse( apiUrl )
def jsonReleaseNotes = new JsonSlurper().parse( apiUrl )
def releaseDate = new Date().format( 'MMMM dd, YYYY' )
def versionId = releseNotes.issues.get( 0 ).fields.fixVersions.get( 0 ).id
def versionId = getVersionId( jsonReleaseNotes, restReleaseVersion )
ReleaseNote releaseNotes = new ReleaseNote( releaseVersion, releaseDate, versionId )
def issuetype
releseNotes.issues.each {
jsonReleaseNotes.issues.each {
issue ->
if ( issuetype != issue.fields.issuetype.name ) {
issuetype = issue.fields.issuetype.name
@ -434,6 +431,17 @@ class ChangeLogFile {
releaseNotes.addEmptyLine()
return releaseNotes.notes
}
private static getVersionId(jsonReleaseNotes, String restReleaseVersion) {
def fixVersions = jsonReleaseNotes.issues.get( 0 ).fields.fixVersions
for ( def fixVersion : fixVersions ) {
if ( fixVersion.name.equals( restReleaseVersion ) ) {
return fixVersion.id
}
}
throw new GradleException( "Unable to determine the version id of the current release." )
}
}
class ReleaseNote {