HHH-13705 Add test for issue
HHH-13705 Add test for issue
This commit is contained in:
parent
47c8a89390
commit
842a155615
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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.inlinedirtychecking;
|
||||||
|
|
||||||
|
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
|
||||||
|
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
public class DirtyCheckEnhancementContext extends EnhancerTestContext {
|
||||||
|
@Override
|
||||||
|
public boolean doExtendedEnhancement(UnloadedClass classDescriptor) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,691 @@
|
||||||
|
/*
|
||||||
|
* 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.inlinedirtychecking;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.Cacheable;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.DiscriminatorColumn;
|
||||||
|
import javax.persistence.DiscriminatorType;
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Inheritance;
|
||||||
|
import javax.persistence.InheritanceType;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.NaturalId;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.stat.Statistics;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.CustomEnhancementContext;
|
||||||
|
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.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@RunWith(BytecodeEnhancerRunner.class)
|
||||||
|
@CustomEnhancementContext({ DirtyCheckEnhancementContext.class, NoDirtyCheckEnhancementContext.class })
|
||||||
|
@TestForIssue(jiraKey = "HHH-13705")
|
||||||
|
public class ManyToOnePropertyAccessByFieldTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
|
||||||
|
super.configureStandardServiceRegistryBuilder( ssrb );
|
||||||
|
ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" );
|
||||||
|
ssrb.applySetting( AvailableSettings.FORMAT_SQL, "false" );
|
||||||
|
ssrb.applySetting( AvailableSettings.GENERATE_STATISTICS, "true" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
|
||||||
|
super.configureSessionFactoryBuilder( sfb );
|
||||||
|
sfb.applyStatisticsSupport( true );
|
||||||
|
sfb.applySecondLevelCacheSupport( false );
|
||||||
|
sfb.applyQueryCacheSupport( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyMetadataSources(MetadataSources sources) {
|
||||||
|
super.applyMetadataSources( sources );
|
||||||
|
sources.addAnnotatedClass( User.class );
|
||||||
|
sources.addAnnotatedClass( Office.class );
|
||||||
|
sources.addAnnotatedClass( Client.class );
|
||||||
|
sources.addAnnotatedClass( Request.class );
|
||||||
|
sources.addAnnotatedClass( InternalRequest.class );
|
||||||
|
sources.addAnnotatedClass( Phone.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
private Long targetUserId;
|
||||||
|
private Long officeId;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
Log log = new Log();
|
||||||
|
log.setCreationDate( OffsetDateTime.now() );
|
||||||
|
|
||||||
|
|
||||||
|
Office office = buildOffice( "The office", "And", Collections.emptySet() );
|
||||||
|
|
||||||
|
session.persist( office );
|
||||||
|
officeId = office.getId();
|
||||||
|
|
||||||
|
User user = new User();
|
||||||
|
user.setOffice( office );
|
||||||
|
user.setClient( office.getClient() );
|
||||||
|
user.setName( "Fab" );
|
||||||
|
user.setLog( log );
|
||||||
|
user.setEmail( "fab@hibernate.org" );
|
||||||
|
|
||||||
|
session.persist( user );
|
||||||
|
|
||||||
|
userId = user.getId();
|
||||||
|
|
||||||
|
user = new User();
|
||||||
|
user.setOffice( office );
|
||||||
|
user.setClient( office.getClient() );
|
||||||
|
user.setName( "And" );
|
||||||
|
user.setLog( log );
|
||||||
|
user.setEmail( "and@hibernate.org" );
|
||||||
|
|
||||||
|
session.persist( user );
|
||||||
|
targetUserId = user.getId();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.createQuery( "delete from Request" ).executeUpdate();
|
||||||
|
session.createQuery( "delete from User" ).executeUpdate();
|
||||||
|
session.createQuery( "delete from Office" ).executeUpdate();
|
||||||
|
session.createQuery( "delete from Client" ).executeUpdate();
|
||||||
|
session.createQuery( "delete from Phone" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersist() {
|
||||||
|
final Statistics stats = sessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
|
||||||
|
InternalRequest internalRequest = new InternalRequest( 1L );
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
User user = session.find( User.class, userId );
|
||||||
|
internalRequest.setUser( user );
|
||||||
|
assertThat( stats.getPrepareStatementCount(), is( 1L ) );
|
||||||
|
|
||||||
|
User targetUser = session.find( User.class, targetUserId );
|
||||||
|
assertThat( stats.getPrepareStatementCount(), is( 2L ) );
|
||||||
|
|
||||||
|
internalRequest.setTargetUser( targetUser );
|
||||||
|
|
||||||
|
session.persist( internalRequest );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assertThat( stats.getPrepareStatementCount(), is( 3L ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelete() {
|
||||||
|
Set<Phone> officePhones = new HashSet<>();
|
||||||
|
officePhones.add( new Phone( 1L, "landline", "028-234-9876" ) );
|
||||||
|
officePhones.add( new Phone( 2L, "mobile", "072-122-9876" ) );
|
||||||
|
Office office = buildOffice( "second office", "Fab", officePhones );
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.save( office );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
Office result = session.find( Office.class, office.id );
|
||||||
|
session.delete( result );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
List<Office> offices = session.createQuery( "from Office" ).list();
|
||||||
|
assertThat( offices.size(), is( 1 ) );
|
||||||
|
assertThat( offices.get( 0 ).getId(), is( officeId ) );
|
||||||
|
|
||||||
|
List<Phone> phones = session.createQuery( "from Phone" ).list();
|
||||||
|
assertThat( phones.size(), is( 0 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() {
|
||||||
|
InternalRequest internalRequest = new InternalRequest( 1L );
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
User user = session.find( User.class, userId );
|
||||||
|
internalRequest.setUser( user );
|
||||||
|
|
||||||
|
User targetUser = session.find( User.class, targetUserId );
|
||||||
|
|
||||||
|
internalRequest.setTargetUser( targetUser );
|
||||||
|
|
||||||
|
session.persist( internalRequest );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
InternalRequest result = session.find( InternalRequest.class, internalRequest.getId() );
|
||||||
|
assertThat( result.getTargetUser().getId(), is( targetUserId ) );
|
||||||
|
assertThat( result.getUser().getId(), is( userId ) );
|
||||||
|
result.setUser( null );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
InternalRequest result = session.find( InternalRequest.class, internalRequest.getId() );
|
||||||
|
assertThat( result.getTargetUser().getId(), is( targetUserId ) );
|
||||||
|
assertThat( result.getUser(), is( nullValue() ) );
|
||||||
|
|
||||||
|
User user = session.find( User.class, userId );
|
||||||
|
result.setTargetUser( user );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
InternalRequest result = session.find( InternalRequest.class, internalRequest.getId() );
|
||||||
|
assertThat( result.getTargetUser().getId(), is( userId ) );
|
||||||
|
assertThat( result.getUser(), is( nullValue() ) );
|
||||||
|
|
||||||
|
User user = session.find( User.class, userId );
|
||||||
|
result.setUser( user );
|
||||||
|
|
||||||
|
Set<Phone> officePhones = new HashSet<>();
|
||||||
|
officePhones.add( new Phone( 1L, "landline", "028-234-9876" ) );
|
||||||
|
officePhones.add( new Phone( 2L, "mobile", "072-122-9876" ) );
|
||||||
|
Office office = buildOffice( "second office", "Fab", officePhones );
|
||||||
|
|
||||||
|
|
||||||
|
session.save( office );
|
||||||
|
|
||||||
|
List<Office> offices = new ArrayList<>();
|
||||||
|
offices.add( office );
|
||||||
|
|
||||||
|
user.setOffices( offices );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
InternalRequest result = session.find( InternalRequest.class, internalRequest.getId() );
|
||||||
|
assertThat( result.getTargetUser().getId(), is( userId ) );
|
||||||
|
User user = result.getUser();
|
||||||
|
assertThat( user.getId(), is( userId ) );
|
||||||
|
List<Office> offices = user.getOffices();
|
||||||
|
assertThat( offices.size(), is( 1 ) );
|
||||||
|
Office office = offices.get( 0 );
|
||||||
|
assertThat( office.getPhones().size(), is( 2 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Office buildOffice(String officename, String clientName, Set<Phone> phones) {
|
||||||
|
Log log = new Log();
|
||||||
|
log.setCreationDate( OffsetDateTime.now() );
|
||||||
|
|
||||||
|
Office office;
|
||||||
|
office = new Office();
|
||||||
|
Client client = new Client();
|
||||||
|
client.setName( clientName );
|
||||||
|
client.setLog( log );
|
||||||
|
|
||||||
|
office.setName( officename );
|
||||||
|
office.setActive( true );
|
||||||
|
office.setDescription( officename );
|
||||||
|
office.setManaged( true );
|
||||||
|
office.setLog( log );
|
||||||
|
office.setClient( client );
|
||||||
|
office.setPhones( phones );
|
||||||
|
|
||||||
|
return office;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Log {
|
||||||
|
@Column(name = "`creationDate`", nullable = false)
|
||||||
|
private OffsetDateTime creationDate;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "`idCreator`")
|
||||||
|
private User creator;
|
||||||
|
|
||||||
|
public OffsetDateTime getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(OffsetDateTime creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public User getCreator() {
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreator(User creator) {
|
||||||
|
this.creator = creator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "User")
|
||||||
|
@Table(name = "`User`")
|
||||||
|
public static class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(length = 120, nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(length = 200, nullable = false, unique = true)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "idOffice")
|
||||||
|
private Office office;
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
private List<Office> offices;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "`idClient`")
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private Log log = new Log();
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Office getOffice() {
|
||||||
|
return office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffice(Office office) {
|
||||||
|
this.office = office;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log getLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLog(Log log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(String hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Office> getOffices() {
|
||||||
|
return offices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffices(List<Office> offices) {
|
||||||
|
this.offices = offices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Office")
|
||||||
|
public static class Office {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(length = 50, nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Boolean isActive = true;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Boolean isManaged = false;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, cascade = CascadeType.ALL)
|
||||||
|
@JoinColumn(name = "idClient")
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
private Set<Phone> phones = new HashSet<>();
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private Log log = new Log();
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(Boolean active) {
|
||||||
|
isActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getManaged() {
|
||||||
|
return isManaged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setManaged(Boolean managed) {
|
||||||
|
isManaged = managed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log getLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLog(Log log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Phone> getPhones() {
|
||||||
|
return phones;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhones(Set<Phone> phones) {
|
||||||
|
this.phones = phones;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Phone")
|
||||||
|
public static class Phone {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@NaturalId
|
||||||
|
@Column(name = "`number`")
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
public Phone() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Phone(Long id, String type, String number) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(String number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Client")
|
||||||
|
public static class Client {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private Log log = new Log();
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log getLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLog(Log log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||||
|
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type", length = 30)
|
||||||
|
@Cacheable
|
||||||
|
@Entity(name = "Request")
|
||||||
|
public static abstract class Request {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "idUser")
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@Column(name = "`creationDate`", nullable = false)
|
||||||
|
private OffsetDateTime creationDate = OffsetDateTime.now();
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(length = 30, nullable = false, name = "status")
|
||||||
|
private StatusRequest status = StatusRequest.REQUESTED;
|
||||||
|
|
||||||
|
Request() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Request(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User userSolicitacao) {
|
||||||
|
this.user = userSolicitacao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(OffsetDateTime creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusRequest getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(StatusRequest status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "InternalRequest")
|
||||||
|
@DiscriminatorValue(value = "INTERN")
|
||||||
|
public static class InternalRequest extends Request {
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "`idTargetUser`")
|
||||||
|
private User targetUser;
|
||||||
|
|
||||||
|
InternalRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InternalRequest(Long id) {
|
||||||
|
super( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public User getTargetUser() {
|
||||||
|
return targetUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetUser(User targetUser) {
|
||||||
|
this.targetUser = targetUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StatusRequest {
|
||||||
|
|
||||||
|
REQUESTED( "requested" ), WAITING( "Feedback waiting" );
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
StatusRequest(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* 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.inlinedirtychecking;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
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.Table;
|
||||||
|
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.stat.Statistics;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.CustomEnhancementContext;
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@RunWith(BytecodeEnhancerRunner.class)
|
||||||
|
@CustomEnhancementContext({ DirtyCheckEnhancementContext.class, NoDirtyCheckEnhancementContext.class })
|
||||||
|
@TestForIssue(jiraKey = "HHH-13705")
|
||||||
|
public class ManyToOneWithEmbeddedAndNotOptionalFieldTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
|
||||||
|
super.configureStandardServiceRegistryBuilder( ssrb );
|
||||||
|
ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" );
|
||||||
|
ssrb.applySetting( AvailableSettings.FORMAT_SQL, "false" );
|
||||||
|
ssrb.applySetting( AvailableSettings.GENERATE_STATISTICS, "true" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
|
||||||
|
super.configureSessionFactoryBuilder( sfb );
|
||||||
|
sfb.applyStatisticsSupport( true );
|
||||||
|
sfb.applySecondLevelCacheSupport( false );
|
||||||
|
sfb.applyQueryCacheSupport( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyMetadataSources(MetadataSources sources) {
|
||||||
|
super.applyMetadataSources( sources );
|
||||||
|
sources.addAnnotatedClass( Client.class );
|
||||||
|
sources.addAnnotatedClass( User.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
User user = new User();
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
|
||||||
|
Log log = new Log();
|
||||||
|
log.setCreationDate( OffsetDateTime.now() );
|
||||||
|
|
||||||
|
Client client = new Client();
|
||||||
|
client.setName( "And" );
|
||||||
|
client.setLog( log );
|
||||||
|
|
||||||
|
|
||||||
|
session.save( client );
|
||||||
|
|
||||||
|
user.setName( "Fab" );
|
||||||
|
|
||||||
|
user.setClient( client );
|
||||||
|
|
||||||
|
session.save( user );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
userId = user.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void load() {
|
||||||
|
final Statistics stats = sessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.find( User.class, userId );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assertThat( stats.getPrepareStatementCount(), is( 1L ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Client")
|
||||||
|
public static class Client {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private Log log = new Log();
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log getLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLog(Log log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "User")
|
||||||
|
@Table(name = "`User`")
|
||||||
|
public static class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(length = 120, nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "`idClient`")
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Log {
|
||||||
|
@Column(name = "`creationDate`", nullable = false)
|
||||||
|
private OffsetDateTime creationDate;
|
||||||
|
|
||||||
|
public OffsetDateTime getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(OffsetDateTime creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* 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.inlinedirtychecking;
|
||||||
|
|
||||||
|
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
|
||||||
|
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
public class NoDirtyCheckEnhancementContext extends EnhancerTestContext {
|
||||||
|
@Override
|
||||||
|
public boolean doDirtyCheckingInline(UnloadedClass classDescriptor) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doExtendedEnhancement(UnloadedClass classDescriptor) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue