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