HHH-11147 - Add test case LazyCollectionDeletedAllowProxyTest
This commit is contained in:
parent
f96eb35f97
commit
3d74724b81
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* 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.bytecode.enhancement.lazy.proxy;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-11147")
|
||||
@RunWith(BytecodeEnhancerRunner.class)
|
||||
@EnhancementOptions(lazyLoading = true)
|
||||
public class LazyCollectionDeletedAllowProxyTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
private Long postId;
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Post.class, Tag.class, AdditionalDetails.class, Label.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
|
||||
super.configureStandardServiceRegistryBuilder( ssrb );
|
||||
|
||||
ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" );
|
||||
ssrb.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" );
|
||||
ssrb.applySetting( AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatingAnAttributeDoesNotDeleteLazyCollectionsTest() {
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "from AdditionalDetails where id = :id" );
|
||||
query.setParameter( "id", postId );
|
||||
AdditionalDetails additionalDetails = (AdditionalDetails) query.getSingleResult();
|
||||
additionalDetails.setDetails( "New data" );
|
||||
s.persist( additionalDetails );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "from Post where id = :id" );
|
||||
query.setParameter( "id", postId );
|
||||
Post retrievedPost = (Post) query.getSingleResult();
|
||||
|
||||
assertFalse( "No tags found", retrievedPost.getTags().isEmpty() );
|
||||
retrievedPost.getTags().forEach( tag -> assertNotNull( tag ) );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "from AdditionalDetails where id = :id" );
|
||||
query.setParameter( "id", postId );
|
||||
AdditionalDetails additionalDetails = (AdditionalDetails) query.getSingleResult();
|
||||
|
||||
Post post = additionalDetails.getPost();
|
||||
assertIsEnhancedProxy( post );
|
||||
post.setMessage( "new message" );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "from Post where id = :id" );
|
||||
query.setParameter( "id", postId );
|
||||
Post retrievedPost = (Post) query.getSingleResult();
|
||||
|
||||
assertEquals( "new message", retrievedPost.getMessage() );
|
||||
assertFalse( "No tags found", retrievedPost.getTags().isEmpty() );
|
||||
retrievedPost.getTags().forEach( tag -> {
|
||||
assertNotNull( tag );
|
||||
assertFalse( "No Labels found", tag.getLabels().isEmpty() );
|
||||
} );
|
||||
|
||||
} );
|
||||
}
|
||||
|
||||
@Before
|
||||
public void prepare() {
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Post post = new Post();
|
||||
|
||||
Tag tag1 = new Tag( "tag1" );
|
||||
Tag tag2 = new Tag( "tag2" );
|
||||
|
||||
Label label1 = new Label( "label1" );
|
||||
Label label2 = new Label( "label2" );
|
||||
|
||||
tag1.addLabel( label1 );
|
||||
tag2.addLabel( label2 );
|
||||
|
||||
Set<Tag> tagSet = new HashSet<>();
|
||||
tagSet.add( tag1 );
|
||||
tagSet.add( tag2 );
|
||||
post.setTags( tagSet );
|
||||
|
||||
AdditionalDetails details = new AdditionalDetails();
|
||||
details.setPost( post );
|
||||
post.setAdditionalDetails( details );
|
||||
details.setDetails( "Some data" );
|
||||
|
||||
postId = (Long) s.save( post );
|
||||
} );
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanData() {
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "from Post" );
|
||||
List<Post> posts = query.getResultList();
|
||||
posts.forEach( post -> {
|
||||
s.delete( post );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
private void assertIsEnhancedProxy(Object entity) {
|
||||
assertThat( entity, instanceOf( PersistentAttributeInterceptable.class ) );
|
||||
|
||||
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) entity;
|
||||
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
|
||||
assertThat( interceptor, instanceOf( EnhancementAsProxyLazinessInterceptor.class ) );
|
||||
}
|
||||
|
||||
// --- //
|
||||
|
||||
@Entity(name = "Tag")
|
||||
@Table(name = "TAG")
|
||||
private static class Tag {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
String name;
|
||||
|
||||
@ManyToMany(cascade = CascadeType.ALL)
|
||||
Set<Label> labels;
|
||||
|
||||
Tag() {
|
||||
}
|
||||
|
||||
Tag(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Set<Label> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public void setLabels(Set<Label> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
public void addLabel(Label label) {
|
||||
if ( this.labels == null ) {
|
||||
this.labels = new HashSet<>();
|
||||
}
|
||||
this.labels.add( label );
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Label")
|
||||
@Table(name = "LABEL")
|
||||
public static class Label {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
String text;
|
||||
|
||||
public Label() {
|
||||
}
|
||||
|
||||
public Label(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Post")
|
||||
@Table(name = "POST")
|
||||
private static class Post {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
String message;
|
||||
|
||||
@ManyToMany(cascade = CascadeType.ALL)
|
||||
Set<Tag> tags;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, mappedBy = "post", cascade = CascadeType.ALL)
|
||||
AdditionalDetails additionalDetails;
|
||||
|
||||
public Set<Tag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(Set<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public AdditionalDetails getAdditionalDetails() {
|
||||
return additionalDetails;
|
||||
}
|
||||
|
||||
public void setAdditionalDetails(AdditionalDetails additionalDetails) {
|
||||
this.additionalDetails = additionalDetails;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "AdditionalDetails")
|
||||
@Table(name = "ADDITIONAL_DETAILS")
|
||||
private static class AdditionalDetails {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String details;
|
||||
|
||||
@OneToOne(optional = false, fetch = FetchType.LAZY)
|
||||
@MapsId
|
||||
Post post;
|
||||
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(String details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
return post;
|
||||
}
|
||||
|
||||
public void setPost(Post post) {
|
||||
this.post = post;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue