Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HHH-11585 - Batch ordering fails for bidirectional one-to-one associa…
…tions (cherry picked from commit f90845c) HHH-11585 : Batch ordering fails for bidirectional one-to-one associations HHH-11585 - Batch ordering fails for bidirectional one-to-one associations - take into consideration legacy one-to-one mappings with composite ids as well (cherry picked from commit acae69f) HHH-11585 : Fix test case to work on pre-5.2 branches HHH-11585 - Batch ordering fails for bidirectional one-to-one associations
- Loading branch information
Showing
11 changed files
with
832 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...c/test/java/org/hibernate/test/insertordering/BatchCountingPreparedStatementObserver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* 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.insertordering; | ||
|
||
import java.lang.reflect.Method; | ||
import java.sql.PreparedStatement; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
import org.hibernate.test.util.jdbc.BasicPreparedStatementObserver; | ||
|
||
/** | ||
* @author Gail Badner | ||
*/ | ||
class BatchCountingPreparedStatementObserver extends BasicPreparedStatementObserver { | ||
private final Map<PreparedStatement, Integer> batchesAddedByPreparedStatement = new LinkedHashMap<PreparedStatement, Integer>(); | ||
|
||
@Override | ||
public void preparedStatementCreated(PreparedStatement preparedStatement, String sql) { | ||
super.preparedStatementCreated( preparedStatement, sql ); | ||
batchesAddedByPreparedStatement.put( preparedStatement, 0 ); | ||
} | ||
|
||
@Override | ||
public void preparedStatementMethodInvoked( | ||
PreparedStatement preparedStatement, | ||
Method method, | ||
Object[] args, | ||
Object invocationReturnValue) { | ||
super.preparedStatementMethodInvoked( preparedStatement, method, args, invocationReturnValue ); | ||
if ( "addBatch".equals( method.getName() ) ) { | ||
batchesAddedByPreparedStatement.put( | ||
preparedStatement, | ||
batchesAddedByPreparedStatement.get( preparedStatement ) + 1 | ||
); | ||
} | ||
} | ||
|
||
public int getNumberOfBatchesAdded(PreparedStatement preparedStatement) { | ||
return batchesAddedByPreparedStatement.get( preparedStatement ); | ||
} | ||
|
||
public void connectionProviderStopped() { | ||
super.connectionProviderStopped(); | ||
batchesAddedByPreparedStatement.clear(); | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
...java/org/hibernate/test/insertordering/InsertOrderingWithBidirectionalMapsIdOneToOne.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* 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.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; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.MapsId; | ||
import javax.persistence.OneToOne; | ||
import javax.persistence.SequenceGenerator; | ||
|
||
import org.hibernate.Session; | ||
import org.hibernate.cfg.Environment; | ||
|
||
import org.hibernate.testing.TestForIssue; | ||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; | ||
import org.hibernate.test.util.jdbc.PreparedStatementProxyConnectionProvider; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
/** | ||
* @author Vlad Mihalcea | ||
*/ | ||
@TestForIssue(jiraKey = "HHH-9864") | ||
public class InsertOrderingWithBidirectionalMapsIdOneToOne | ||
extends BaseNonConfigCoreFunctionalTestCase { | ||
|
||
private BatchCountingPreparedStatementObserver preparedStatementObserver = new BatchCountingPreparedStatementObserver(); | ||
private PreparedStatementProxyConnectionProvider connectionProvider = new PreparedStatementProxyConnectionProvider( | ||
preparedStatementObserver | ||
); | ||
|
||
@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 { | ||
Session session = openSession(); | ||
session.getTransaction().begin(); | ||
{ | ||
Person worker = new Person(); | ||
Person homestay = new Person(); | ||
|
||
Address home = new Address(); | ||
Address office = new Address(); | ||
|
||
home.addPerson( homestay ); | ||
|
||
office.addPerson( worker ); | ||
|
||
session.persist( home ); | ||
session.persist( office ); | ||
|
||
connectionProvider.clear(); | ||
} | ||
session.getTransaction().commit(); | ||
session.close(); | ||
|
||
PreparedStatement addressPreparedStatement = preparedStatementObserver.getPreparedStatement( | ||
"insert into Address (ID) values (?)" ); | ||
assertEquals( 2, preparedStatementObserver.getNumberOfBatchesAdded( addressPreparedStatement ) ); | ||
|
||
PreparedStatement personPreparedStatement = preparedStatementObserver.getPreparedStatement( | ||
"insert into Person (address_ID) values (?)" ); | ||
assertEquals( 2, preparedStatementObserver.getNumberOfBatchesAdded( personPreparedStatement ) ); | ||
} | ||
|
||
@Entity(name = "Address") | ||
public static class Address { | ||
@Id | ||
@Column(name = "ID", nullable = false) | ||
@SequenceGenerator(name = "ID", sequenceName = "ADDRESS_SEQ") | ||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID") | ||
private Long id; | ||
|
||
@OneToOne(mappedBy = "address", cascade = CascadeType.PERSIST) | ||
private Person person; | ||
|
||
public void addPerson(Person person) { | ||
this.person = person; | ||
person.address = this; | ||
} | ||
} | ||
|
||
@Entity(name = "Person") | ||
public static class Person { | ||
@Id | ||
private Long id; | ||
|
||
@OneToOne | ||
@MapsId | ||
private Address address; | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
.../test/java/org/hibernate/test/insertordering/InsertOrderingWithBidirectionalOneToOne.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* 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.insertordering; | ||
|
||
import org.hibernate.Session; | ||
import org.hibernate.cfg.Environment; | ||
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 org.hibernate.test.util.jdbc.PreparedStatementProxyConnectionProvider; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
/** | ||
* @author Vlad Mihalcea | ||
*/ | ||
@TestForIssue(jiraKey = "HHH-9864") | ||
public class InsertOrderingWithBidirectionalOneToOne | ||
extends BaseNonConfigCoreFunctionalTestCase { | ||
private BatchCountingPreparedStatementObserver preparedStatementObserver = new BatchCountingPreparedStatementObserver(); | ||
private PreparedStatementProxyConnectionProvider connectionProvider = new PreparedStatementProxyConnectionProvider( | ||
preparedStatementObserver | ||
); | ||
|
||
@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 { | ||
Session session = openSession(); | ||
session.getTransaction().begin(); | ||
{ | ||
Person worker = new Person(); | ||
Person homestay = new Person(); | ||
|
||
Address home = new Address(); | ||
Address office = new Address(); | ||
|
||
home.addPerson( homestay ); | ||
|
||
office.addPerson( worker ); | ||
|
||
session.persist( home ); | ||
session.persist( office ); | ||
|
||
connectionProvider.clear(); | ||
} | ||
session.getTransaction().commit(); | ||
session.close(); | ||
|
||
PreparedStatement addressPreparedStatement = preparedStatementObserver.getPreparedStatement( | ||
"insert into Address (ID) values (?)" | ||
); | ||
assertEquals( 2, preparedStatementObserver.getNumberOfBatchesAdded( addressPreparedStatement ) ); | ||
|
||
PreparedStatement personPreparedStatement = preparedStatementObserver.getPreparedStatement( | ||
"insert into Person (address_ID, ID) values (?, ?)" | ||
); | ||
assertEquals( 2, preparedStatementObserver.getNumberOfBatchesAdded( personPreparedStatement ) ); | ||
} | ||
|
||
@Entity(name = "Address") | ||
public static class Address { | ||
@Id | ||
@Column(name = "ID", nullable = false) | ||
@SequenceGenerator(name = "ID", sequenceName = "ADDRESS_SEQ") | ||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID") | ||
private Long id; | ||
|
||
@OneToOne(mappedBy = "address", cascade = CascadeType.PERSIST) | ||
private Person person; | ||
|
||
public void addPerson(Person person) { | ||
this.person = person; | ||
person.address = this; | ||
} | ||
} | ||
|
||
@Entity(name = "Person") | ||
public static class Person { | ||
@Id | ||
@Column(name = "ID", nullable = false) | ||
@SequenceGenerator(name = "ID", sequenceName = "ADDRESS_SEQ") | ||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID") | ||
private Long id; | ||
|
||
@OneToOne | ||
private Address address; | ||
} | ||
} |
Oops, something went wrong.