Re-enabled additional tests
This commit is contained in:
parent
4806398ecc
commit
82de2b0a3f
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright 2014 JBoss Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.hibernate.orm.test.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
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 org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/**
|
||||
* This template demonstrates how to develop a test case for Hibernate ORM, using its built-in unit test framework.
|
||||
* Although ORMStandaloneTestCase is perfectly acceptable as a reproducer, usage of this class is much preferred.
|
||||
* Since we nearly always include a regression test with bug fixes, providing your reproducer using this method
|
||||
* simplifies the process.
|
||||
* <p>
|
||||
* What's even better? Fork hibernate-orm itself, add your test case directly to a module's unit tests, then
|
||||
* submit it as a PR!
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
BagDuplicatesTest.Parent.class,
|
||||
BagDuplicatesTest.Child.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class BagDuplicatesTest {
|
||||
|
||||
@Test
|
||||
public void HHH10385Test(SessionFactoryScope scope) {
|
||||
|
||||
Long parentId = scope.fromTransaction(
|
||||
session -> {
|
||||
Parent parent = new Parent();
|
||||
session.persist( parent );
|
||||
session.flush();
|
||||
return parent.getId();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent parent = session.get( Parent.class, parentId );
|
||||
Child child1 = new Child();
|
||||
child1.setName( "child1" );
|
||||
child1.setParent( parent );
|
||||
parent.addChild( child1 );
|
||||
parent = (Parent) session.merge( parent );
|
||||
session.flush();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
||||
Parent parent = session.get( Parent.class, parentId );
|
||||
assertEquals( 1, parent.getChildren().size() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
public static class Parent {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true)
|
||||
private List<Child> children = new ArrayList<>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void addChild(Child child) {
|
||||
children.add( child );
|
||||
child.setParent( this );
|
||||
}
|
||||
|
||||
public void removeChild(Child child) {
|
||||
children.remove( child );
|
||||
child.setParent( null );
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
public static class Child {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
private Parent parent;
|
||||
|
||||
public Child() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Child{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* 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.orm.test.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(annotatedClasses = {
|
||||
BagElementNullBasicTest.AnEntity.class,
|
||||
BagElementNullBasicTest.NullableElementsEntity.class
|
||||
})
|
||||
@SessionFactory
|
||||
public class BagElementNullBasicTest {
|
||||
|
||||
@Test
|
||||
public void testPersistNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( null );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.add( null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-13651")
|
||||
public void addNullValueToNullableCollections(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
NullableElementsEntity e = new NullableElementsEntity();
|
||||
e.list.add( null );
|
||||
session.persist( e );
|
||||
session.flush();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNull(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNullWithExtraValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
e.aCollection.add( "ghi" );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id, scope ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id, scope ).size() );
|
||||
assertEquals( "ghi", e.aCollection.get( 0 ) );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private List getCollectionElementRows(int id, SessionFactoryScope scope) {
|
||||
return scope.fromTransaction(
|
||||
session ->
|
||||
session.createNativeQuery(
|
||||
"SELECT aCollection FROM AnEntity_aCollection where AnEntity_id = " + id
|
||||
).list()
|
||||
);
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "AnEntity")
|
||||
public static class AnEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "AnEntity_aCollection", joinColumns = { @JoinColumn(name = "AnEntity_id") })
|
||||
@OrderBy
|
||||
private List<String> aCollection = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "NullableElementsEntity")
|
||||
public static class NullableElementsEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "e_2_string", joinColumns = @JoinColumn(name = "e_id"))
|
||||
@Column(name = "string_value", unique = false, nullable = true, insertable = true, updatable = true)
|
||||
private List<String> list = new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.bag;
|
||||
package org.hibernate.orm.test.collection.bag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.bag;
|
||||
package org.hibernate.orm.test.collection.bag;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
|
@ -10,7 +10,7 @@
|
|||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.collection.bag">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.collection.bag">
|
||||
|
||||
<class name="BagOwner">
|
||||
<id name="name" column="NAME" type="string" />
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.bag;
|
||||
package org.hibernate.orm.test.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -15,7 +15,7 @@ import java.util.List;
|
|||
public class Order {
|
||||
private Long id;
|
||||
|
||||
private List<Item> items = new ArrayList<Item>();
|
||||
private List<Item> items = new ArrayList<>();
|
||||
|
||||
public Order() {
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.bag;
|
||||
package org.hibernate.orm.test.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -17,26 +17,26 @@ import javax.persistence.ManyToOne;
|
|||
import javax.persistence.OneToMany;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests related to contains operations on a PersistentBag.
|
||||
*
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class PersistentBagContainsTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Order.class,
|
||||
Item.class
|
||||
};
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
PersistentBagContainsTest.Order.class,
|
||||
PersistentBagContainsTest.Item.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class PersistentBagContainsTest {
|
||||
|
||||
/**
|
||||
* This test does not verify how equals is implemented for Bags,
|
||||
|
@ -45,8 +45,8 @@ public class PersistentBagContainsTest extends BaseCoreFunctionalTestCase {
|
|||
*/
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-5409")
|
||||
public void testContains() {
|
||||
Order _order = doInHibernate( this::sessionFactory, session -> {
|
||||
public void testContains(SessionFactoryScope scope) {
|
||||
Order _order = scope.fromTransaction( session -> {
|
||||
Order order = new Order();
|
||||
session.persist( order );
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class PersistentBagContainsTest extends BaseCoreFunctionalTestCase {
|
|||
return order;
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
scope.inTransaction( session -> {
|
||||
Item item1 = new Item();
|
||||
item1.setName( "i1" );
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class PersistentBagContainsTest extends BaseCoreFunctionalTestCase {
|
|||
assertTrue( order.getItems().contains( item2 ) );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
scope.inTransaction( session -> {
|
||||
Order order = session.find( Order.class, _order.getId() );
|
||||
session.delete( order );
|
||||
} );
|
||||
|
@ -90,7 +90,7 @@ public class PersistentBagContainsTest extends BaseCoreFunctionalTestCase {
|
|||
private Long id;
|
||||
|
||||
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<Item> items = new ArrayList<Item>();
|
||||
private List<Item> items = new ArrayList<>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.orm.test.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentBag;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentBag.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsNoColumnInsert.class)
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/collection/bag/Mappings.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class PersistentBagTest {
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying(SessionFactoryScope scope) {
|
||||
BagOwner parent = new BagOwner( "root" );
|
||||
BagOwner child = new BagOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
child.setParent( parent );
|
||||
BagOwner otherChild = new BagOwner( "c2" );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentBag...
|
||||
PersistentBag children = (PersistentBag) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, reason = " HANA doesn't support tables consisting of only a single auto-generated column")
|
||||
public void testMergePersistentEntityWithNewOneToManyElements(SessionFactoryScope scope) {
|
||||
|
||||
Long orderId = scope.fromTransaction(
|
||||
session -> {
|
||||
Order order = new Order();
|
||||
|
||||
session.persist( order );
|
||||
session.flush();
|
||||
return order.getId();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order order = session.get( Order.class, orderId );
|
||||
Item item1 = new Item();
|
||||
item1.setName( "i1" );
|
||||
Item item2 = new Item();
|
||||
item2.setName( "i2" );
|
||||
order.addItem( item1 );
|
||||
order.addItem( item2 );
|
||||
order = (Order) session.merge( order );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order order = session.get( Order.class, orderId );
|
||||
assertEquals( 2, order.getItems().size() );
|
||||
session.delete( order );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.idbag;
|
||||
package org.hibernate.orm.test.collection.idbag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -21,28 +21,26 @@ import org.hibernate.annotations.CollectionId;
|
|||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
AnEntity.class
|
||||
};
|
||||
}
|
||||
@DomainModel(
|
||||
annotatedClasses = IdBagElementNullBasicTest.AnEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
public class IdBagElementNullBasicTest {
|
||||
|
||||
@Test
|
||||
public void testPersistNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testPersistNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( null );
|
||||
session.persist( e );
|
||||
|
@ -50,49 +48,49 @@ public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void addNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.add( null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNull() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testUpdateNonNullValueToNull(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
session.persist( e );
|
||||
|
@ -100,29 +98,29 @@ public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNullWithExtraValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testUpdateNonNullValueToNullWithExtraValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
e.aCollection.add( "ghi" );
|
||||
|
@ -131,11 +129,11 @@ public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id, scope ).size() );
|
||||
if ( "def".equals( e.aCollection.get( 0 ) ) ) {
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
|
@ -145,20 +143,20 @@ public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id, scope ).size() );
|
||||
assertEquals( "ghi", e.aCollection.get( 0 ) );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private List getCollectionElementRows(int id) {
|
||||
return doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
private List getCollectionElementRows(int id, SessionFactoryScope scope) {
|
||||
return scope.fromTransaction(
|
||||
session -> {
|
||||
return session.createNativeQuery(
|
||||
"SELECT aCollection FROM AnEntity_aCollection where AnEntity_id = " + id
|
||||
).list();
|
||||
|
@ -181,6 +179,6 @@ public class IdBagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
type = @Type(type = "long"),
|
||||
generator = "increment"
|
||||
)
|
||||
private List<String> aCollection = new ArrayList<String>();
|
||||
private List<String> aCollection = new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.idbag;
|
||||
package org.hibernate.orm.test.collection.idbag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.collection.idbag">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.collection.idbag">
|
||||
|
||||
<class name="IdbagOwner">
|
||||
<id name="name" column="NAME" type="string" />
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.orm.test.collection.idbag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentIdentifierBag;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentIdentifierBag
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/collection/idbag/Mappings.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class PersistentIdBagTest {
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying(SessionFactoryScope scope) {
|
||||
IdbagOwner parent = new IdbagOwner( "root" );
|
||||
IdbagOwner child = new IdbagOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
IdbagOwner otherChild = new IdbagOwner( "c2" );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentBag...
|
||||
PersistentIdentifierBag children = (PersistentIdentifierBag) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.list;
|
||||
package org.hibernate.orm.test.collection.list;
|
||||
|
||||
|
||||
/**
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.list;
|
||||
package org.hibernate.orm.test.collection.list;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -17,28 +17,26 @@ import javax.persistence.JoinColumn;
|
|||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
AnEntity.class
|
||||
};
|
||||
}
|
||||
@DomainModel(
|
||||
annotatedClasses = ListElementNullBasicTest.AnEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
public class ListElementNullBasicTest {
|
||||
|
||||
@Test
|
||||
public void testPersistNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testPersistNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( null );
|
||||
session.persist( e );
|
||||
|
@ -46,49 +44,49 @@ public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void addNullValue(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.add( null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNull() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testUpdateNonNullValueToNull(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
session.persist( e );
|
||||
|
@ -96,29 +94,29 @@ public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId, scope ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId, scope ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNullToNonNull() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
public void testUpdateNonNullValueToNullToNonNull(SessionFactoryScope scope) {
|
||||
int entityId = scope.fromTransaction(
|
||||
session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
e.aCollection.add( "ghi" );
|
||||
|
@ -127,29 +125,29 @@ public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id, scope ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id, scope ).size() );
|
||||
e.aCollection.set( 0, "not null" );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id, scope ).size() );
|
||||
assertEquals( "not null", e.aCollection.get( 0 ) );
|
||||
assertEquals( "ghi", e.aCollection.get( 1 ) );
|
||||
session.delete( e );
|
||||
|
@ -157,9 +155,9 @@ public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
private List getCollectionElementRows(int id) {
|
||||
return doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
private List getCollectionElementRows(int id, SessionFactoryScope scope) {
|
||||
return scope.fromTransaction(
|
||||
session -> {
|
||||
return session.createNativeQuery(
|
||||
"SELECT aCollection FROM AnEntity_aCollection where AnEntity_id = " + id
|
||||
).list();
|
||||
|
@ -177,6 +175,6 @@ public class ListElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
|||
@ElementCollection
|
||||
@CollectionTable(name = "AnEntity_aCollection", joinColumns = { @JoinColumn(name = "AnEntity_id") })
|
||||
@OrderColumn
|
||||
private List<String> aCollection = new ArrayList<String>();
|
||||
private List<String> aCollection = new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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.orm.test.collection.list;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/**
|
||||
* Test initially developed for HHH-9195
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
ListIndexReferenceFromListElementTest.LocalOrder.class,
|
||||
ListIndexReferenceFromListElementTest.LocalLineItem.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class ListIndexReferenceFromListElementTest {
|
||||
|
||||
@BeforeEach
|
||||
public void before(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LocalOrder localOrder = new LocalOrder();
|
||||
localOrder.makeLineItem( "Shoes" );
|
||||
localOrder.makeLineItem( "Socks" );
|
||||
session.save( localOrder );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete LocalLineItem" ).executeUpdate();
|
||||
session.createQuery( "delete LocalOrder" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIt(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LocalOrder order = session.byId( LocalOrder.class ).load( 1 );
|
||||
assertEquals( 2, order.lineItems.size() );
|
||||
LocalLineItem shoes = order.lineItems.get( 0 );
|
||||
LocalLineItem socks = order.lineItems.get( 1 );
|
||||
assertEquals( "Shoes", shoes.name );
|
||||
assertEquals( 0, shoes.position );
|
||||
assertEquals( 1, socks.position );
|
||||
order.lineItems.remove( socks );
|
||||
order.lineItems.add( 0, socks );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LocalOrder order = session.byId( LocalOrder.class ).load( 1 );
|
||||
assertEquals( 2, order.lineItems.size() );
|
||||
LocalLineItem socks = order.lineItems.get( 0 );
|
||||
LocalLineItem shoes = order.lineItems.get( 1 );
|
||||
assertEquals( "Shoes", shoes.name );
|
||||
assertEquals( 0, socks.position );
|
||||
assertEquals( 1, shoes.position );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "LocalOrder")
|
||||
@Table(name = "LocalOrder")
|
||||
public static class LocalOrder {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@OrderColumn(name = "position")
|
||||
public List<LocalLineItem> lineItems = new ArrayList<>();
|
||||
|
||||
public LocalOrder() {
|
||||
}
|
||||
|
||||
public LocalLineItem makeLineItem(String name) {
|
||||
LocalLineItem lineItem = new LocalLineItem( name, this );
|
||||
lineItems.add( lineItem );
|
||||
return lineItem;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "LocalLineItem")
|
||||
@Table(name = "LocalLineItem")
|
||||
public static class LocalLineItem {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
public String name;
|
||||
@ManyToOne
|
||||
@JoinColumn
|
||||
public LocalOrder order;
|
||||
@Column(insertable = false, updatable = false)
|
||||
public int position;
|
||||
|
||||
public LocalLineItem() {
|
||||
}
|
||||
|
||||
public LocalLineItem(String name, LocalOrder order) {
|
||||
this.name = name;
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.list;
|
||||
package org.hibernate.orm.test.collection.list;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.collection.list">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.collection.list">
|
||||
|
||||
<class name="ListOwner">
|
||||
<id name="name" column="NAME" type="string" />
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collection.list;
|
||||
package org.hibernate.orm.test.collection.list;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -15,7 +15,7 @@ import java.util.List;
|
|||
public class Order {
|
||||
private Integer id;
|
||||
private String code;
|
||||
private List<LineItem> lineItems = new ArrayList<LineItem>();
|
||||
private List<LineItem> lineItems = new ArrayList<>();
|
||||
|
||||
public Order() {
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* 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.orm.test.collection.list;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.collection.internal.PersistentList;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.sql.SimpleSelect;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentList
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/collection/list/Mappings.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class PersistentListTest {
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-5732")
|
||||
public void testInverseListIndex(SessionFactoryScope scope) {
|
||||
// make sure no one changes the mapping
|
||||
SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||
final CollectionPersister collectionPersister = sessionFactory
|
||||
.getCollectionPersister( ListOwner.class.getName() + ".children" );
|
||||
assertTrue( collectionPersister.isInverse() );
|
||||
|
||||
// do some creations...
|
||||
ListOwner root = new ListOwner( "root" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
ListOwner child1 = new ListOwner( "c1" );
|
||||
root.getChildren().add( child1 );
|
||||
child1.setParent( root );
|
||||
ListOwner child2 = new ListOwner( "c2" );
|
||||
root.getChildren().add( child2 );
|
||||
child2.setParent( root );
|
||||
|
||||
session.save( root );
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// now, make sure the list-index column gotten written...
|
||||
scope.inTransaction(
|
||||
session2 -> {
|
||||
session2.doWork(
|
||||
connection -> {
|
||||
final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister;
|
||||
SimpleSelect select = new SimpleSelect( sessionFactory.getDialect() )
|
||||
.setTableName( queryableCollection.getTableName() )
|
||||
.addColumn( "NAME" )
|
||||
.addColumn( "LIST_INDEX" )
|
||||
.addCondition( "NAME", "<>", "?" );
|
||||
PreparedStatement preparedStatement = ( (SessionImplementor) session2 ).getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( select.toStatementString() );
|
||||
preparedStatement.setString( 1, "root" );
|
||||
ResultSet resultSet = ( (SessionImplementor) session2 ).getJdbcCoordinator()
|
||||
.getResultSetReturn()
|
||||
.extract( preparedStatement );
|
||||
Map<String, Integer> valueMap = new HashMap<String, Integer>();
|
||||
while ( resultSet.next() ) {
|
||||
final String name = resultSet.getString( 1 );
|
||||
assertFalse( "NAME column was null", resultSet.wasNull() );
|
||||
final int position = resultSet.getInt( 2 );
|
||||
assertFalse( "LIST_INDEX column was null", resultSet.wasNull() );
|
||||
valueMap.put( name, position );
|
||||
}
|
||||
assertEquals( 2, valueMap.size() );
|
||||
|
||||
// c1 should be list index 0
|
||||
assertEquals( Integer.valueOf( 0 ), valueMap.get( "c1" ) );
|
||||
// c2 should be list index 1
|
||||
assertEquals( Integer.valueOf( 1 ), valueMap.get( "c2" ) );
|
||||
}
|
||||
);
|
||||
session2.delete( root );
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-5732")
|
||||
public void testInverseListIndex2(SessionFactoryScope scope) {
|
||||
// make sure no one changes the mapping
|
||||
SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||
final CollectionPersister collectionPersister = sessionFactory
|
||||
.getCollectionPersister( Order.class.getName() + ".lineItems" );
|
||||
assertTrue( collectionPersister.isInverse() );
|
||||
|
||||
// do some creations...
|
||||
Order order = new Order( "acme-1" );
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
order.addLineItem( "abc", 2 );
|
||||
order.addLineItem( "def", 200 );
|
||||
order.addLineItem( "ghi", 13 );
|
||||
session.save( order );
|
||||
}
|
||||
);
|
||||
|
||||
// now, make sure the list-index column gotten written...
|
||||
scope.inTransaction(
|
||||
session2 -> {
|
||||
session2.doWork(
|
||||
connection -> {
|
||||
final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister;
|
||||
SimpleSelect select = new SimpleSelect( sessionFactory.getDialect() )
|
||||
.setTableName( queryableCollection.getTableName() )
|
||||
.addColumn( "ORDER_ID" )
|
||||
.addColumn( "INDX" )
|
||||
.addColumn( "PRD_CODE" );
|
||||
PreparedStatement preparedStatement = ( (SessionImplementor) session2 ).getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( select.toStatementString() );
|
||||
ResultSet resultSet = ( (SessionImplementor) session2 ).getJdbcCoordinator()
|
||||
.getResultSetReturn()
|
||||
.extract( preparedStatement );
|
||||
Map<String, Integer> valueMap = new HashMap<String, Integer>();
|
||||
while ( resultSet.next() ) {
|
||||
final int fk = resultSet.getInt( 1 );
|
||||
assertFalse( "Collection key (FK) column was null", resultSet.wasNull() );
|
||||
final int indx = resultSet.getInt( 2 );
|
||||
assertFalse( "List index column was null", resultSet.wasNull() );
|
||||
final String prodCode = resultSet.getString( 3 );
|
||||
assertFalse( "Prod code column was null", resultSet.wasNull() );
|
||||
valueMap.put( prodCode, indx );
|
||||
}
|
||||
assertEquals( 3, valueMap.size() );
|
||||
assertEquals( Integer.valueOf( 0 ), valueMap.get( "abc" ) );
|
||||
assertEquals( Integer.valueOf( 1 ), valueMap.get( "def" ) );
|
||||
assertEquals( Integer.valueOf( 2 ), valueMap.get( "ghi" ) );
|
||||
}
|
||||
);
|
||||
session2.delete( order );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying(SessionFactoryScope scope) {
|
||||
ListOwner parent = new ListOwner( "root" );
|
||||
ListOwner child = new ListOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
child.setParent( parent );
|
||||
ListOwner otherChild = new ListOwner( "c2" );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentList...
|
||||
PersistentList children = (PersistentList) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,676 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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.orm.test.collection.multisession;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.collection.internal.AbstractPersistentCollection;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
MultipleSessionCollectionTest.Parent.class,
|
||||
MultipleSessionCollectionTest.Child.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class MultipleSessionCollectionTest {
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSaveOrUpdateOwnerWithCollectionInNewSessionBeforeFlush(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// try to save the same entity in a new session before flushing the first session
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
try {
|
||||
s2.getTransaction().begin();
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
//expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSaveOrUpdateOwnerWithCollectionInNewSessionAfterFlush(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.saveOrUpdate( p );
|
||||
s1.flush();
|
||||
|
||||
// try to save the same entity in a new session after flushing the first session
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSaveOrUpdateOwnerWithUninitializedCollectionInNewSession(SessionFactoryScope scope) {
|
||||
|
||||
Parent parent = new Parent();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
session.persist( parent );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
Parent p = s1.get( Parent.class, parent.id );
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
|
||||
// try to save the same entity (with an uninitialized collection) in a new session
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
//expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// should still be able to initialize collection, modify and commit in first session
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
Hibernate.initialize( p.children );
|
||||
p.children.add( new Child() );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( 2, pGet.children.size() );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSaveOrUpdateOwnerWithInitializedCollectionInNewSession(SessionFactoryScope scope) {
|
||||
Parent parent = new Parent();
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> session.persist( parent )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
Parent p = s1.get( Parent.class, parent.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// try to save the same entity (with an initialized collection) in a new session
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testCopyPersistentCollectionReferenceBeforeFlush(SessionFactoryScope scope) {
|
||||
Parent parent = new Parent();
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.persist( parent );
|
||||
|
||||
// Copy p.children into a different Parent before flush and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = parent.children;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testCopyPersistentCollectionReferenceAfterFlush(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.persist( p );
|
||||
s1.flush();
|
||||
|
||||
// Copy p.children into a different Parent after flush and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testCopyUninitializedCollectionReferenceAfterGet(SessionFactoryScope scope) {
|
||||
Parent parent = new Parent();
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> session.persist( parent )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
Parent p = s1.get( Parent.class, parent.id );
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
|
||||
// Copy p.children (uninitialized) into a different Parent and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testCopyInitializedCollectionReferenceAfterGet(SessionFactoryScope scope) {
|
||||
Parent parent = new Parent();
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> session.persist( parent )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
Parent p = s1.get( Parent.class, parent.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// Copy p.children (initialized) into a different Parent.children and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testCopyInitializedCollectionReferenceToNewEntityCollectionRoleAfterGet(SessionFactoryScope scope) {
|
||||
Parent parent = new Parent();
|
||||
Child c = new Child();
|
||||
parent.children.add( c );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> session.persist( parent )
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
Parent p = s1.get( Parent.class, parent.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// Copy p.children (initialized) into a different Parent.oldChildren (note different collection role)
|
||||
// and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.oldChildren = p.children;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent pGet = session.get( Parent.class, parent.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testDeleteCommitCopyToNewOwnerInNewSession(SessionFactoryScope scope) {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( p1 );
|
||||
session.save( p2 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
s1.flush();
|
||||
s1.getTransaction().commit();
|
||||
|
||||
// need to commit after flushing; otherwise, will get lock failure when try to move the collection below
|
||||
|
||||
assertNull( s1.getPersistenceContext().getEntry( p1 ) );
|
||||
CollectionEntry ceChildren = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p1.children );
|
||||
CollectionEntry ceNickNames = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p1.nickNames );
|
||||
assertNull( ceChildren );
|
||||
assertNull( ceNickNames );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.children ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldChildren ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.nickNames ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() );
|
||||
|
||||
// Assign the deleted collection to a different entity with same collection role (p2.nickNames)
|
||||
|
||||
p2.nickNames = p1.nickNames;
|
||||
scope.inTransaction(
|
||||
s2 -> s2.saveOrUpdate( p2 )
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testDeleteCommitCopyToNewOwnerNewCollectionRoleInNewSession(SessionFactoryScope scope) {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( p1 );
|
||||
session.save( p2 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
s1.flush();
|
||||
s1.getTransaction().commit();
|
||||
|
||||
// need to commit after flushing; otherwise, will get lock failure when try to move the collection below
|
||||
|
||||
assertNull( s1.getPersistenceContext().getEntry( p1 ) );
|
||||
CollectionEntry ceChildren = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p1.children );
|
||||
CollectionEntry ceNickNames = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p1.nickNames );
|
||||
assertNull( ceChildren );
|
||||
assertNull( ceNickNames );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.children ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldChildren ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.nickNames ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() );
|
||||
|
||||
// Assign the deleted collection to a different entity with different collection role (p2.oldNickNames)
|
||||
|
||||
p2.oldNickNames = p1.nickNames;
|
||||
|
||||
scope.inTransaction(
|
||||
s2 -> s2.saveOrUpdate( p2 )
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testDeleteCopyToNewOwnerInNewSessionBeforeFlush(SessionFactoryScope scope) {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( p1 );
|
||||
session.save( p2 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.delete( p1 );
|
||||
|
||||
// Assign the deleted collection to a different entity with same collection role (p2.nickNames)
|
||||
// before committing delete.
|
||||
|
||||
p2.nickNames = p1.nickNames;
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p2 );
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testDeleteCopyToNewOwnerNewCollectionRoleInNewSessionBeforeFlush(SessionFactoryScope scope) {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.save( p1 );
|
||||
session.save( p2 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
s1 -> {
|
||||
s1.delete( p1 );
|
||||
|
||||
// Assign the deleted collection to a different entity with different collection role (p2.oldNickNames)
|
||||
// before committing delete.
|
||||
|
||||
p2.oldNickNames = p1.nickNames;
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p2 );
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
// expected
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@ElementCollection
|
||||
private Set<String> nickNames = new HashSet<String>();
|
||||
|
||||
@ElementCollection
|
||||
private Set<String> oldNickNames = new HashSet<String>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> children = new HashSet<Child>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> oldChildren = new HashSet<Child>();
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "Child")
|
||||
public static class Child {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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.orm.test.collection.multisession;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.collection.internal.AbstractPersistentCollection;
|
||||
import org.hibernate.collection.internal.PersistentSet;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.logger.LoggerInspectionRule;
|
||||
import org.hibernate.testing.logger.Triggerable;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.Rule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
MultipleSessionCollectionWarningTest.Parent.class,
|
||||
MultipleSessionCollectionWarningTest.Child.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class MultipleSessionCollectionWarningTest {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPersistentCollection.class );
|
||||
|
||||
@Rule
|
||||
public LoggerInspectionRule logInspection = new LoggerInspectionRule( LOG );
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSetCurrentSessionOverwritesNonConnectedSesssion(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
try {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = s1.getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're setting a new session when the collection already
|
||||
// has a non-null session (and the collection is not "connected" to that session);
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that other than inspection).
|
||||
s2.saveOrUpdate( p );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should be overwritten with s2
|
||||
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
}
|
||||
finally {
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
s1.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testSetCurrentSessionOverwritesNonConnectedSesssionFlushed(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
try {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// flush the session so that p.children will contain its role
|
||||
s1.flush();
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = s1.getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're setting a new session when the collection already
|
||||
// has a non-null session (and the collection is not "connected" to that session);
|
||||
// The collection role and key should be included in the message (no way to test that other than inspection).
|
||||
s2.saveOrUpdate( p );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should be overwritten with s2
|
||||
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
}
|
||||
finally {
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
s1.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testUnsetSessionCannotOverwriteNonConnectedSesssion(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
try {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = s1.getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session.
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
}
|
||||
finally {
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
finally {
|
||||
s1.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testUnsetSessionCannotOverwriteConnectedSesssion(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
try {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// The collection is "connected" to s1 because it contains the CollectionEntry
|
||||
CollectionEntry ce = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
}
|
||||
finally {
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
s1.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-9518")
|
||||
public void testUnsetSessionCannotOverwriteConnectedSesssionFlushed(SessionFactoryScope scope) {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
scope.inSession(
|
||||
s1 -> {
|
||||
s1.getTransaction().begin();
|
||||
try {
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// flush the session so that p.children will contain its role
|
||||
s1.flush();
|
||||
|
||||
// The collection is "connected" to s1 because it contains the CollectionEntry
|
||||
CollectionEntry ce = s1.getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
scope.inSession(
|
||||
s2 -> {
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// The collection role and key should be included in the message (no way to test that other than inspection).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
}
|
||||
finally {
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
s1.getTransaction().rollback();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
@Table(name = "Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> children = new HashSet<>();
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Table(name = "Child")
|
||||
public static class Child {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package org.hibernate.orm.test.collection.nonInsertable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-13236")
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
NonInsertableColumnTest.Parent.class,
|
||||
NonInsertableColumnTest.Child.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class NonInsertableColumnTest {
|
||||
|
||||
@Test
|
||||
public void test(SessionFactoryScope scope) {
|
||||
Long parentId = scope.fromTransaction(
|
||||
session -> {
|
||||
Child child = new Child();
|
||||
child.field = "Test";
|
||||
child.nonInsertable = "nonInsertable";
|
||||
child.nonUpdatable = "nonUpdatable";
|
||||
|
||||
Parent parent = new Parent();
|
||||
parent.children = Arrays.asList( child );
|
||||
|
||||
session.persist( parent );
|
||||
|
||||
session.flush();
|
||||
|
||||
return parent.id;
|
||||
}
|
||||
);
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
Parent loaded = session.get( Parent.class, parentId );
|
||||
assertEquals( "nonUpdatable", loaded.children.get( 0 ).nonUpdatable );
|
||||
assertNull( loaded.children.get( 0 ).nonInsertable );
|
||||
assertEquals( "Test", loaded.children.get( 0 ).field );
|
||||
assertEquals( "Test", loaded.children.get( 0 ).shadowField );
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
public Long id;
|
||||
|
||||
@ElementCollection
|
||||
public List<Child> children;
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class Child {
|
||||
|
||||
@Column(name = "field")
|
||||
public String field;
|
||||
|
||||
@Column(insertable = false)
|
||||
public String nonInsertable;
|
||||
|
||||
@Column(updatable = false)
|
||||
public String nonUpdatable;
|
||||
|
||||
@Column(name = "field", insertable = false, updatable = false)
|
||||
public String shadowField;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collectionalias;
|
||||
package org.hibernate.orm.test.collectionalias;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.orm.test.collectionalias;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
/**
|
||||
* @author Dave Stephan
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
TableBId.class,
|
||||
TableB.class,
|
||||
TableA.class,
|
||||
ATable.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class CollectionAliasTest {
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-7545")
|
||||
@Test
|
||||
public void test(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
||||
ATable aTable = new ATable( 1 );
|
||||
TableB tableB = new TableB(
|
||||
new TableBId( 1, "a", "b" )
|
||||
);
|
||||
aTable.getTablebs().add( tableB );
|
||||
tableB.setTablea( aTable );
|
||||
session.save( aTable );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
ATable aTable = (ATable) session.createQuery(
|
||||
"select distinct tablea from ATable tablea LEFT JOIN FETCH tablea.tablebs " )
|
||||
.uniqueResult();
|
||||
assertEquals( new Integer( 1 ), aTable.getFirstId() );
|
||||
assertEquals( 1, aTable.getTablebs().size() );
|
||||
TableB tableB = aTable.getTablebs().get( 0 );
|
||||
assertSame( aTable, tableB.getTablea() );
|
||||
assertEquals( new Integer( 1 ), tableB.getId().getFirstId() );
|
||||
assertEquals( "a", tableB.getId().getSecondId() );
|
||||
assertEquals( "b", tableB.getId().getThirdId() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.orm.test.collectionalias;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
/**
|
||||
* The bug fixed by HHH-7545 showed showed different results depending on the order
|
||||
* in which entity mappings were processed.
|
||||
*
|
||||
* This mappings are in the opposite order here than in CollectionAliasTest.
|
||||
*
|
||||
* @Author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
ATable.class,
|
||||
TableA.class,
|
||||
TableB.class,
|
||||
TableBId.class,
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class ReorderedMappingsCollectionAliasTest {
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-7545")
|
||||
@Test
|
||||
public void test(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
ATable aTable = new ATable( 1 );
|
||||
TableB tableB = new TableB(
|
||||
new TableBId( 1, "a", "b" )
|
||||
);
|
||||
aTable.getTablebs().add( tableB );
|
||||
tableB.setTablea( aTable );
|
||||
session.save( aTable );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inSession(
|
||||
session -> {
|
||||
ATable aTable = (ATable) session.createQuery(
|
||||
"select distinct tablea from ATable tablea LEFT JOIN FETCH tablea.tablebs " )
|
||||
.uniqueResult();
|
||||
assertEquals( new Integer( 1 ), aTable.getFirstId() );
|
||||
assertEquals( 1, aTable.getTablebs().size() );
|
||||
TableB tableB = aTable.getTablebs().get( 0 );
|
||||
assertSame( aTable, tableB.getTablea() );
|
||||
assertEquals( new Integer( 1 ), tableB.getId().getFirstId() );
|
||||
assertEquals( "a", tableB.getId().getSecondId() );
|
||||
assertEquals( "b", tableB.getId().getThirdId() );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collectionalias;
|
||||
package org.hibernate.orm.test.collectionalias;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collectionalias;
|
||||
package org.hibernate.orm.test.collectionalias;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.collectionalias;
|
||||
package org.hibernate.orm.test.collectionalias;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 JBoss Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.hibernate.test.collection.bag;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* This template demonstrates how to develop a test case for Hibernate ORM, using its built-in unit test framework.
|
||||
* Although ORMStandaloneTestCase is perfectly acceptable as a reproducer, usage of this class is much preferred.
|
||||
* Since we nearly always include a regression test with bug fixes, providing your reproducer using this method
|
||||
* simplifies the process.
|
||||
*
|
||||
* What's even better? Fork hibernate-orm itself, add your test case directly to a module's unit tests, then
|
||||
* submit it as a PR!
|
||||
*/
|
||||
public class BagDuplicatesTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
// Add your entities here.
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
// If you use *.hbm.xml mappings, instead of annotations, add the mappings here.
|
||||
@Override
|
||||
protected String[] getMappings() {
|
||||
return new String[] {
|
||||
// "Foo.hbm.xml",
|
||||
// "Bar.hbm.xml"
|
||||
};
|
||||
}
|
||||
// If those mappings reside somewhere other than resources/org/hibernate/test, change this.
|
||||
@Override
|
||||
protected String getBaseForMappings() {
|
||||
return "org/hibernate/test/";
|
||||
}
|
||||
|
||||
// Add in any settings that are specific to your test. See resources/hibernate.properties for the defaults.
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
super.configure( configuration );
|
||||
|
||||
configuration.setProperty( AvailableSettings.SHOW_SQL, "true" );
|
||||
}
|
||||
|
||||
// Add your tests, using standard JUnit.
|
||||
@Test
|
||||
public void HHH10385Test() throws Exception {
|
||||
// BaseCoreFunctionalTestCase automatically creates the SessionFactory and provides the Session.
|
||||
Session session = null;
|
||||
Transaction transaction = null;
|
||||
|
||||
Long parentId = null;
|
||||
|
||||
try {
|
||||
session = openSession();
|
||||
transaction = session.beginTransaction();
|
||||
|
||||
Parent parent = new Parent();
|
||||
session.persist(parent);
|
||||
session.flush();
|
||||
parentId = parent.getId();
|
||||
|
||||
transaction.commit();
|
||||
} catch (HibernateException e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
fail(e.getMessage());
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
session = openSession();
|
||||
transaction = session.beginTransaction();
|
||||
|
||||
Parent parent = session.get(Parent.class, parentId);
|
||||
Child child1 = new Child();
|
||||
child1.setName("child1");
|
||||
child1.setParent(parent);
|
||||
parent.addChild(child1);
|
||||
parent = (Parent) session.merge(parent);
|
||||
session.flush();
|
||||
//assertEquals(1, parent.getChildren().size());
|
||||
|
||||
transaction.commit();
|
||||
} catch (HibernateException e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
fail(e.getMessage());
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
session = openSession();
|
||||
transaction = session.beginTransaction();
|
||||
|
||||
Parent parent = session.get(Parent.class, parentId);
|
||||
assertEquals(1, parent.getChildren().size());
|
||||
|
||||
transaction.commit();
|
||||
} catch (HibernateException e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
fail(e.getMessage());
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
public static class Parent {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true)
|
||||
private List<Child> children = new ArrayList<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void addChild(Child child) {
|
||||
children.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
|
||||
public void removeChild(Child child) {
|
||||
children.remove(child);
|
||||
child.setParent(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
public static class Child {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
private Parent parent;
|
||||
|
||||
public Child() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Child{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
* 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.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class BagElementNullBasicTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
AnEntity.class,
|
||||
NullableElementsEntity.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( null );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addNullValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
e.aCollection.add( null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-13651")
|
||||
public void addNullValueToNullableCollections() {
|
||||
try (final Session s = sessionFactory().openSession()) {
|
||||
final Transaction tx = s.beginTransaction();
|
||||
NullableElementsEntity e = new NullableElementsEntity();
|
||||
e.list.add( null );
|
||||
s.persist( e );
|
||||
s.flush();
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNull() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( entityId ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 0, e.aCollection.size() );
|
||||
assertEquals( 0, getCollectionElementRows( entityId ).size() );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNonNullValueToNullWithExtraValue() {
|
||||
int entityId = doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = new AnEntity();
|
||||
e.aCollection.add( "def" );
|
||||
e.aCollection.add( "ghi" );
|
||||
session.persist( e );
|
||||
return e.id;
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 2, e.aCollection.size() );
|
||||
assertEquals( 2, getCollectionElementRows( e.id ).size() );
|
||||
e.aCollection.set( 0, null );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
AnEntity e = session.get( AnEntity.class, entityId );
|
||||
assertEquals( 1, e.aCollection.size() );
|
||||
assertEquals( 1, getCollectionElementRows( e.id ).size() );
|
||||
assertEquals( "ghi", e.aCollection.get( 0 ) );
|
||||
session.delete( e );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private List getCollectionElementRows(int id) {
|
||||
return doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
return session.createNativeQuery(
|
||||
"SELECT aCollection FROM AnEntity_aCollection where AnEntity_id = " + id
|
||||
).list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="AnEntity")
|
||||
public static class AnEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "AnEntity_aCollection", joinColumns = { @JoinColumn( name = "AnEntity_id" ) })
|
||||
@OrderBy
|
||||
private List<String> aCollection = new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="NullableElementsEntity")
|
||||
public static class NullableElementsEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name="e_2_string", joinColumns=@JoinColumn(name="e_id"))
|
||||
@Column(name="string_value", unique = false, nullable = true, insertable = true, updatable = true)
|
||||
private List<String> list = new ArrayList<String>();
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* 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.collection.bag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.collection.internal.PersistentBag;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentBag.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@RequiresDialectFeature(DialectChecks.SupportsNoColumnInsert.class)
|
||||
public class PersistentBagTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "collection/bag/Mappings.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying() {
|
||||
BagOwner parent = new BagOwner( "root" );
|
||||
BagOwner child = new BagOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
child.setParent( parent );
|
||||
BagOwner otherChild = new BagOwner( "c2" );
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentBag...
|
||||
PersistentBag children = ( PersistentBag ) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(value = AbstractHANADialect.class, comment = " HANA doesn't support tables consisting of only a single auto-generated column")
|
||||
public void testMergePersistentEntityWithNewOneToManyElements() {
|
||||
Order order = new Order();
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( order );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.getTransaction().begin();
|
||||
order = s.get( Order.class, order.getId() );
|
||||
Item item1 = new Item();
|
||||
item1.setName( "i1" );
|
||||
Item item2 = new Item();
|
||||
item2.setName( "i2" );
|
||||
order.addItem( item1 );
|
||||
order.addItem( item2 );
|
||||
order = (Order) s.merge( order );
|
||||
//s.flush();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.getTransaction().begin();
|
||||
order = s.get( Order.class, order.getId() );
|
||||
assertEquals( 2, order.getItems().size() );
|
||||
s.delete( order );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* 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.collection.idbag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.collection.internal.PersistentIdentifierBag;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentIdentifierBag
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PersistentIdBagTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "collection/idbag/Mappings.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying() {
|
||||
IdbagOwner parent = new IdbagOwner( "root" );
|
||||
IdbagOwner child = new IdbagOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
IdbagOwner otherChild = new IdbagOwner( "c2" );
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentBag...
|
||||
PersistentIdentifierBag children = ( PersistentIdentifierBag ) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* 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.collection.list;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test initially developed for HHH-9195
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListIndexReferenceFromListElementTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
@Entity( name = "LocalOrder" )
|
||||
@Table( name = "LocalOrder" )
|
||||
public static class LocalOrder {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
@OneToMany( mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY )
|
||||
@OrderColumn( name = "position" )
|
||||
public List<LocalLineItem> lineItems = new ArrayList<LocalLineItem>();
|
||||
|
||||
public LocalOrder() {
|
||||
}
|
||||
|
||||
public LocalLineItem makeLineItem(String name) {
|
||||
LocalLineItem lineItem = new LocalLineItem( name, this );
|
||||
lineItems.add( lineItem );
|
||||
return lineItem;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "LocalLineItem" )
|
||||
@Table( name = "LocalLineItem" )
|
||||
public static class LocalLineItem {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
public String name;
|
||||
@ManyToOne
|
||||
@JoinColumn
|
||||
public LocalOrder order;
|
||||
@Column( insertable = false, updatable = false )
|
||||
public int position;
|
||||
|
||||
public LocalLineItem() {
|
||||
}
|
||||
|
||||
public LocalLineItem(String name, LocalOrder order) {
|
||||
this.name = name;
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] { LocalOrder.class, LocalLineItem.class };
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
Session s = sessionFactory().openSession();
|
||||
s.beginTransaction();
|
||||
LocalOrder localOrder = new LocalOrder();
|
||||
localOrder.makeLineItem( "Shoes" );
|
||||
localOrder.makeLineItem( "Socks" );
|
||||
s.save( localOrder );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
Session s = sessionFactory().openSession();
|
||||
s.beginTransaction();
|
||||
s.createQuery( "delete LocalLineItem" ).executeUpdate();
|
||||
s.createQuery( "delete LocalOrder" ).executeUpdate();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIt() {
|
||||
{
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LocalOrder order = s.byId( LocalOrder.class ).load( 1 );
|
||||
assertEquals( 2, order.lineItems.size() );
|
||||
LocalLineItem shoes = order.lineItems.get( 0 );
|
||||
LocalLineItem socks = order.lineItems.get( 1 );
|
||||
assertEquals( "Shoes", shoes.name );
|
||||
assertEquals( 0, shoes.position );
|
||||
assertEquals( 1, socks.position );
|
||||
order.lineItems.remove( socks );
|
||||
order.lineItems.add( 0, socks );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
{
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LocalOrder order = s.byId( LocalOrder.class ).load( 1 );
|
||||
assertEquals( 2, order.lineItems.size() );
|
||||
LocalLineItem socks = order.lineItems.get( 0 );
|
||||
LocalLineItem shoes = order.lineItems.get( 1 );
|
||||
assertEquals( "Shoes", shoes.name );
|
||||
assertEquals( 0, socks.position );
|
||||
assertEquals( 1, shoes.position );
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* 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.collection.list;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.collection.internal.PersistentList;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.jdbc.Work;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.sql.SimpleSelect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests related to operations on a PersistentList
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PersistentListTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "collection/list/Mappings.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-5732" )
|
||||
public void testInverseListIndex() {
|
||||
// make sure no one changes the mapping
|
||||
final CollectionPersister collectionPersister = sessionFactory().getCollectionPersister( ListOwner.class.getName() + ".children" );
|
||||
assertTrue( collectionPersister.isInverse() );
|
||||
|
||||
// do some creations...
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
ListOwner root = new ListOwner( "root" );
|
||||
ListOwner child1 = new ListOwner( "c1" );
|
||||
root.getChildren().add( child1 );
|
||||
child1.setParent( root );
|
||||
ListOwner child2 = new ListOwner( "c2" );
|
||||
root.getChildren().add( child2 );
|
||||
child2.setParent( root );
|
||||
|
||||
session.save( root );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
// now, make sure the list-index column gotten written...
|
||||
final Session session2 = openSession();
|
||||
session2.beginTransaction();
|
||||
session2.doWork(
|
||||
new Work() {
|
||||
@Override
|
||||
public void execute(Connection connection) throws SQLException {
|
||||
final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister;
|
||||
SimpleSelect select = new SimpleSelect( getDialect() )
|
||||
.setTableName( queryableCollection.getTableName() )
|
||||
.addColumn( "NAME" )
|
||||
.addColumn( "LIST_INDEX" )
|
||||
.addCondition( "NAME", "<>", "?" );
|
||||
PreparedStatement preparedStatement = ((SessionImplementor)session2).getJdbcCoordinator().getStatementPreparer().prepareStatement( select.toStatementString() );
|
||||
preparedStatement.setString( 1, "root" );
|
||||
ResultSet resultSet = ((SessionImplementor)session2).getJdbcCoordinator().getResultSetReturn().extract( preparedStatement );
|
||||
Map<String, Integer> valueMap = new HashMap<String, Integer>();
|
||||
while ( resultSet.next() ) {
|
||||
final String name = resultSet.getString( 1 );
|
||||
assertFalse( "NAME column was null", resultSet.wasNull() );
|
||||
final int position = resultSet.getInt( 2 );
|
||||
assertFalse( "LIST_INDEX column was null", resultSet.wasNull() );
|
||||
valueMap.put( name, position );
|
||||
}
|
||||
assertEquals( 2, valueMap.size() );
|
||||
|
||||
// c1 should be list index 0
|
||||
assertEquals( Integer.valueOf( 0 ), valueMap.get( "c1" ) );
|
||||
// c2 should be list index 1
|
||||
assertEquals( Integer.valueOf( 1 ), valueMap.get( "c2" ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
session2.delete( root );
|
||||
session2.getTransaction().commit();
|
||||
session2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-5732" )
|
||||
public void testInverseListIndex2() {
|
||||
// make sure no one changes the mapping
|
||||
final CollectionPersister collectionPersister = sessionFactory().getCollectionPersister( Order.class.getName() + ".lineItems" );
|
||||
assertTrue( collectionPersister.isInverse() );
|
||||
|
||||
// do some creations...
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
Order order = new Order( "acme-1" );
|
||||
order.addLineItem( "abc", 2 );
|
||||
order.addLineItem( "def", 200 );
|
||||
order.addLineItem( "ghi", 13 );
|
||||
session.save( order );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
// now, make sure the list-index column gotten written...
|
||||
final Session session2 = openSession();
|
||||
session2.beginTransaction();
|
||||
session2.doWork(
|
||||
new Work() {
|
||||
@Override
|
||||
public void execute(Connection connection) throws SQLException {
|
||||
final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister;
|
||||
SimpleSelect select = new SimpleSelect( getDialect() )
|
||||
.setTableName( queryableCollection.getTableName() )
|
||||
.addColumn( "ORDER_ID" )
|
||||
.addColumn( "INDX" )
|
||||
.addColumn( "PRD_CODE" );
|
||||
PreparedStatement preparedStatement = ((SessionImplementor)session2).getJdbcCoordinator().getStatementPreparer().prepareStatement( select.toStatementString() );
|
||||
ResultSet resultSet = ((SessionImplementor)session2).getJdbcCoordinator().getResultSetReturn().extract( preparedStatement );
|
||||
Map<String, Integer> valueMap = new HashMap<String, Integer>();
|
||||
while ( resultSet.next() ) {
|
||||
final int fk = resultSet.getInt( 1 );
|
||||
assertFalse( "Collection key (FK) column was null", resultSet.wasNull() );
|
||||
final int indx = resultSet.getInt( 2 );
|
||||
assertFalse( "List index column was null", resultSet.wasNull() );
|
||||
final String prodCode = resultSet.getString( 3 );
|
||||
assertFalse( "Prod code column was null", resultSet.wasNull() );
|
||||
valueMap.put( prodCode, indx );
|
||||
}
|
||||
assertEquals( 3, valueMap.size() );
|
||||
assertEquals( Integer.valueOf( 0 ), valueMap.get( "abc" ) );
|
||||
assertEquals( Integer.valueOf( 1 ), valueMap.get( "def" ) );
|
||||
assertEquals( Integer.valueOf( 2 ), valueMap.get( "ghi" ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
session2.delete( order );
|
||||
session2.getTransaction().commit();
|
||||
session2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteMethodDirtying() {
|
||||
ListOwner parent = new ListOwner( "root" );
|
||||
ListOwner child = new ListOwner( "c1" );
|
||||
parent.getChildren().add( child );
|
||||
child.setParent( parent );
|
||||
ListOwner otherChild = new ListOwner( "c2" );
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.save( parent );
|
||||
session.flush();
|
||||
// at this point, the list on parent has now been replaced with a PersistentList...
|
||||
PersistentList children = (PersistentList) parent.getChildren();
|
||||
|
||||
assertFalse( children.remove( otherChild ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
ArrayList otherCollection = new ArrayList();
|
||||
otherCollection.add( child );
|
||||
assertFalse( children.retainAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
otherCollection = new ArrayList();
|
||||
otherCollection.add( otherChild );
|
||||
assertFalse( children.removeAll( otherCollection ) );
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
children.clear();
|
||||
session.delete( child );
|
||||
assertTrue( children.isDirty() );
|
||||
|
||||
session.flush();
|
||||
|
||||
children.clear();
|
||||
assertFalse( children.isDirty() );
|
||||
|
||||
session.delete( parent );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
}
|
|
@ -1,694 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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.test.collection.multisession;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.collection.internal.AbstractPersistentCollection;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class MultipleSessionCollectionTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSaveOrUpdateOwnerWithCollectionInNewSessionBeforeFlush() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// try to save the same entity in a new session before flushing the first session
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSaveOrUpdateOwnerWithCollectionInNewSessionAfterFlush() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
s1.flush();
|
||||
|
||||
// try to save the same entity in a new session after flushing the first session
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSaveOrUpdateOwnerWithUninitializedCollectionInNewSession() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( p );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
p = s1.get( Parent.class, p.id );
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
|
||||
// try to save the same entity (with an uninitialized collection) in a new session
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to initialize collection, modify and commit in first session
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
Hibernate.initialize( p.children );
|
||||
p.children.add( new Child() );
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( 2, pGet.children.size());
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSaveOrUpdateOwnerWithInitializedCollectionInNewSession() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( p );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
p = s1.get( Parent.class, p.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// try to save the same entity (with an initialized collection) in a new session
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testCopyPersistentCollectionReferenceBeforeFlush() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.persist( p );
|
||||
|
||||
// Copy p.children into a different Parent before flush and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testCopyPersistentCollectionReferenceAfterFlush() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.persist( p );
|
||||
s1.flush();
|
||||
|
||||
// Copy p.children into a different Parent after flush and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testCopyUninitializedCollectionReferenceAfterGet() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( p );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
p = s1.get( Parent.class, p.id );
|
||||
assertFalse( Hibernate.isInitialized( p.children ) );
|
||||
|
||||
// Copy p.children (uninitialized) into a different Parent and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testCopyInitializedCollectionReferenceAfterGet() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( p );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
p = s1.get( Parent.class, p.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// Copy p.children (initialized) into a different Parent.children and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.children = p.children;
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testCopyInitializedCollectionReferenceToNewEntityCollectionRoleAfterGet() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
s.persist( p );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
p = s1.get( Parent.class, p.id );
|
||||
Hibernate.initialize( p.children );
|
||||
|
||||
// Copy p.children (initialized) into a different Parent.oldChildren (note different collection role)
|
||||
// and try to save in new session.
|
||||
|
||||
Parent pWithSameChildren = new Parent();
|
||||
pWithSameChildren.oldChildren = p.children;
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( pWithSameChildren );
|
||||
s2.getTransaction().commit();
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit in first session
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
Parent pGet = s1.get( Parent.class, p.id );
|
||||
assertEquals( c.id, pGet.children.iterator().next().id );
|
||||
session.delete( pGet );
|
||||
s1.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testDeleteCommitCopyToNewOwnerInNewSession() {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.save( p1 );
|
||||
s1.save( p2 );
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
s1.flush();
|
||||
s1.getTransaction().commit();
|
||||
|
||||
// need to commit after flushing; otherwise, will get lock failure when try to move the collection below
|
||||
|
||||
assertNull( ( (SessionImplementor) s1 ).getPersistenceContext().getEntry( p1 ) );
|
||||
CollectionEntry ceChildren = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.children );
|
||||
CollectionEntry ceNickNames = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.nickNames );
|
||||
assertNull( ceChildren );
|
||||
assertNull( ceNickNames );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.children ).getSession() );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.oldChildren ).getSession() );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.nickNames ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() );
|
||||
|
||||
// Assign the deleted collection to a different entity with same collection role (p2.nickNames)
|
||||
|
||||
p2.nickNames = p1.nickNames;
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
s2.saveOrUpdate( p2 );
|
||||
s2.getTransaction().commit();
|
||||
s2.close();
|
||||
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testDeleteCommitCopyToNewOwnerNewCollectionRoleInNewSession() {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.save( p1 );
|
||||
s1.save( p2 );
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
s1.flush();
|
||||
s1.getTransaction().commit();
|
||||
|
||||
// need to commit after flushing; otherwise, will get lock failure when try to move the collection below
|
||||
|
||||
assertNull( ( (SessionImplementor) s1 ).getPersistenceContext().getEntry( p1 ) );
|
||||
CollectionEntry ceChildren = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.children );
|
||||
CollectionEntry ceNickNames = ( (SessionImplementor) s1 ).getPersistenceContext().getCollectionEntry( (PersistentCollection) p1.nickNames );
|
||||
assertNull( ceChildren );
|
||||
assertNull( ceNickNames );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.children ).getSession() );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.oldChildren ).getSession() );
|
||||
assertNull( ( ( AbstractPersistentCollection) p1.nickNames ).getSession() );
|
||||
assertNull( ( (AbstractPersistentCollection) p1.oldNickNames ).getSession() );
|
||||
|
||||
// Assign the deleted collection to a different entity with different collection role (p2.oldNickNames)
|
||||
|
||||
p2.oldNickNames = p1.nickNames;
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
s2.saveOrUpdate( p2 );
|
||||
s2.getTransaction().commit();
|
||||
s2.close();
|
||||
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testDeleteCopyToNewOwnerInNewSessionBeforeFlush() {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.save( p1 );
|
||||
s1.save( p2 );
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
|
||||
// Assign the deleted collection to a different entity with same collection role (p2.nickNames)
|
||||
// before committing delete.
|
||||
|
||||
p2.nickNames = p1.nickNames;
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p2 );
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit the original delete
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testDeleteCopyToNewOwnerNewCollectionRoleInNewSessionBeforeFlush() {
|
||||
Parent p1 = new Parent();
|
||||
p1.nickNames.add( "nick" );
|
||||
Parent p2 = new Parent();
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.save( p1 );
|
||||
s1.save( p2 );
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
|
||||
s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.delete( p1 );
|
||||
|
||||
// Assign the deleted collection to a different entity with different collection role (p2.oldNickNames)
|
||||
// before committing delete.
|
||||
|
||||
p2.oldNickNames = p1.nickNames;
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
try {
|
||||
s2.saveOrUpdate( p2 );
|
||||
fail( "should have thrown HibernateException" );
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
log.error( ex );
|
||||
s2.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
s2.close();
|
||||
}
|
||||
|
||||
// should still be able to commit the original delete
|
||||
s1.getTransaction().commit();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@ElementCollection
|
||||
private Set<String> nickNames = new HashSet<String>();
|
||||
|
||||
@ElementCollection
|
||||
private Set<String> oldNickNames = new HashSet<String>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> children = new HashSet<Child>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> oldChildren = new HashSet<Child>();
|
||||
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="Child")
|
||||
public static class Child {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,328 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. 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.test.collection.multisession;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.collection.internal.AbstractPersistentCollection;
|
||||
import org.hibernate.collection.internal.PersistentSet;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.spi.CollectionEntry;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.testing.logger.LoggerInspectionRule;
|
||||
import org.hibernate.testing.logger.Triggerable;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class MultipleSessionCollectionWarningTest extends BaseCoreFunctionalTestCase {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPersistentCollection.class );
|
||||
|
||||
@Rule
|
||||
public LoggerInspectionRule logInspection = new LoggerInspectionRule( LOG );
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSetCurrentSessionOverwritesNonConnectedSesssion() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're setting a new session when the collection already
|
||||
// has a non-null session (and the collection is not "connected" to that session);
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that other than inspection).
|
||||
s2.saveOrUpdate( p );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should be overwritten with s2
|
||||
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
s2.getTransaction().rollback();
|
||||
s2.close();
|
||||
|
||||
s1.getTransaction().rollback();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testSetCurrentSessionOverwritesNonConnectedSesssionFlushed() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// flush the session so that p.children will contain its role
|
||||
s1.flush();
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're setting a new session when the collection already
|
||||
// has a non-null session (and the collection is not "connected" to that session);
|
||||
// The collection role and key should be included in the message (no way to test that other than inspection).
|
||||
s2.saveOrUpdate( p );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should be overwritten with s2
|
||||
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
s2.getTransaction().rollback();
|
||||
s2.close();
|
||||
|
||||
s1.getTransaction().rollback();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testUnsetSessionCannotOverwriteNonConnectedSesssion() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// Now remove the collection from the PersistenceContext without unsetting its session
|
||||
// This should never be done in practice; it is done here only to test that the warning
|
||||
// gets logged. s1 will not function properly so the transaction will ultimately need
|
||||
// to be rolled-back.
|
||||
|
||||
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
|
||||
.removeCollectionEntry( (PersistentSet) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should still be s1; the collection is no longer "connected" because its
|
||||
// CollectionEntry has been removed.
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session.
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
s2.getTransaction().rollback();
|
||||
s2.close();
|
||||
|
||||
s1.getTransaction().rollback();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testUnsetSessionCannotOverwriteConnectedSesssion() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// The collection is "connected" to s1 because it contains the CollectionEntry
|
||||
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// Since s1 was not flushed, the collection role will not be known (no way to test that).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
s2.getTransaction().rollback();
|
||||
s2.close();
|
||||
|
||||
s1.getTransaction().rollback();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9518" )
|
||||
public void testUnsetSessionCannotOverwriteConnectedSesssionFlushed() {
|
||||
Parent p = new Parent();
|
||||
Child c = new Child();
|
||||
p.children.add( c );
|
||||
|
||||
Session s1 = openSession();
|
||||
s1.getTransaction().begin();
|
||||
s1.saveOrUpdate( p );
|
||||
|
||||
// flush the session so that p.children will contain its role
|
||||
s1.flush();
|
||||
|
||||
// The collection is "connected" to s1 because it contains the CollectionEntry
|
||||
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
|
||||
.getCollectionEntry( (PersistentCollection) p.children );
|
||||
assertNotNull( ce );
|
||||
|
||||
// the collection session should be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
Session s2 = openSession();
|
||||
s2.getTransaction().begin();
|
||||
|
||||
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
|
||||
assertFalse( triggerable.wasTriggered() );
|
||||
|
||||
// The following should trigger warning because we're unsetting a different session
|
||||
// We should not do this in practice; it is done here only to force the warning.
|
||||
// The collection role and key should be included in the message (no way to test that other than inspection).
|
||||
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
|
||||
|
||||
assertTrue( triggerable.wasTriggered() );
|
||||
|
||||
// collection's session should still be s1
|
||||
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
|
||||
|
||||
s2.getTransaction().rollback();
|
||||
s2.close();
|
||||
|
||||
s1.getTransaction().rollback();
|
||||
s1.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@JoinColumn
|
||||
private Set<Child> children = new HashSet<Child>();
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name="Child")
|
||||
public static class Child {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
package org.hibernate.test.collection.nonInsertable;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-13236")
|
||||
public class NonInsertableColumnTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
super.configure( configuration );
|
||||
|
||||
configuration.setProperty( AvailableSettings.SHOW_SQL, "true" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Session session = null;
|
||||
Transaction transaction = null;
|
||||
|
||||
try {
|
||||
session = openSession();
|
||||
transaction = session.beginTransaction();
|
||||
|
||||
Child child = new Child();
|
||||
child.field = "Test";
|
||||
child.nonInsertable = "nonInsertable";
|
||||
child.nonUpdatable = "nonUpdatable";
|
||||
|
||||
Parent parent = new Parent();
|
||||
parent.children = Arrays.asList(child);
|
||||
|
||||
session.persist(parent);
|
||||
|
||||
session.flush();
|
||||
|
||||
transaction.commit();
|
||||
|
||||
session.clear();
|
||||
|
||||
Parent loaded = session.get(Parent.class, parent.id);
|
||||
assertEquals("nonUpdatable", loaded.children.get(0).nonUpdatable);
|
||||
assertNull(loaded.children.get(0).nonInsertable);
|
||||
assertEquals("Test", loaded.children.get(0).field);
|
||||
assertEquals("Test", loaded.children.get(0).shadowField);
|
||||
} catch (HibernateException e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
fail(e.getMessage());
|
||||
} finally {
|
||||
if (session != null) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name="Parent")
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
public Long id;
|
||||
|
||||
@ElementCollection
|
||||
public List<Child> children;
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class Child {
|
||||
|
||||
@Column(name="field")
|
||||
public String field;
|
||||
|
||||
@Column(insertable = false)
|
||||
public String nonInsertable;
|
||||
|
||||
@Column(updatable = false)
|
||||
public String nonUpdatable;
|
||||
|
||||
@Column(name="field", insertable = false, updatable = false)
|
||||
public String shadowField;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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.collectionalias;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* @author Dave Stephan
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class CollectionAliasTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@TestForIssue( jiraKey = "HHH-7545" )
|
||||
@Test
|
||||
public void test() {
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
ATable aTable = new ATable( 1 );
|
||||
TableB tableB = new TableB(
|
||||
new TableBId( 1, "a", "b" )
|
||||
);
|
||||
aTable.getTablebs().add( tableB );
|
||||
tableB.setTablea( aTable );
|
||||
s.save( aTable );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
aTable = (ATable) s.createQuery( "select distinct tablea from ATable tablea LEFT JOIN FETCH tablea.tablebs " ).uniqueResult();
|
||||
assertEquals( new Integer( 1 ), aTable.getFirstId() );
|
||||
assertEquals( 1, aTable.getTablebs().size() );
|
||||
tableB = aTable.getTablebs().get( 0 );
|
||||
assertSame( aTable, tableB.getTablea() );
|
||||
assertEquals( new Integer( 1 ), tableB.getId().getFirstId() );
|
||||
assertEquals( "a", tableB.getId().getSecondId() );
|
||||
assertEquals( "b", tableB.getId().getThirdId() );
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
TableBId.class,
|
||||
TableB.class,
|
||||
TableA.class,
|
||||
ATable.class
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* 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.collectionalias;
|
||||
|
||||
/**
|
||||
* The bug fixed by HHH-7545 showed showed different results depending on the order
|
||||
* in which entity mappings were processed.
|
||||
*
|
||||
* This mappings are in the opposite order here than in CollectionAliasTest.
|
||||
*
|
||||
* @Author Gail Badner
|
||||
*/
|
||||
public class ReorderedMappingsCollectionAliasTest extends CollectionAliasTest {
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
ATable.class,
|
||||
TableA.class,
|
||||
TableB.class,
|
||||
TableBId.class,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ package org.hibernate.testing.orm.junit;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
|
||||
/**
|
||||
* Container class for different implementation of the {@link DialectFeatureCheck} interface.
|
||||
*
|
||||
|
@ -58,6 +57,12 @@ abstract public class DialectFeatureChecks {
|
|||
}
|
||||
}
|
||||
|
||||
public static class SupportsNoColumnInsert implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
return dialect.supportsNoColumnsInsert();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SupportsResultSetPositioningOnForwardOnlyCursorCheck implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
return dialect.supportsResultSetPositionQueryMethodsOnForwardOnlyCursor();
|
||||
|
|
Loading…
Reference in New Issue