HHH-12436 : Added test cases

(cherry picked from commit 925c737096)
This commit is contained in:
Gail Badner 2018-10-26 18:34:22 -07:00 committed by gbadner
parent 7e73de1cc9
commit f0117e8874
7 changed files with 4108 additions and 0 deletions

View File

@ -0,0 +1,893 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.ConstraintMode;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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 static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class OptionalEagerInEmbeddableNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonManyToOneJoinIgnore.class,
PersonManyToOneSelectIgnore.class,
PersonOneToOneJoinIgnore.class,
PersonOneToOneSelectIgnore.class,
PersonMapsIdJoinIgnore.class,
PersonMapsIdSelectIgnore.class,
PersonPkjcJoinException.class,
PersonPkjcJoinIgnore.class,
PersonPkjcSelectException.class,
PersonPkjcSelectIgnore.class,
PersonMapsIdColumnJoinIgnore.class,
PersonMapsIdColumnSelectIgnore.class,
City.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@Test
public void testOneToOneJoinIgnore() {
setupTest( PersonOneToOneJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonOneToOneJoinIgnore.class, 1L );
}
@Test
public void testOneToOneSelectIgnore() {
setupTest( PersonOneToOneSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonOneToOneSelectIgnore.class, 1L );
}
@Test
public void testManyToOneJoinIgnore() {
setupTest( PersonManyToOneJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonManyToOneJoinIgnore.class, 1L );
}
@Test
public void testManyToOneSelectIgnore() {
setupTest( PersonManyToOneSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonManyToOneSelectIgnore.class, 1L );
}
@Test
public void testPkjcOneToOneJoinException() {
setupTest( PersonPkjcJoinException.class, 1L, false );
// optional @OneToOne @PKJC implicitly maps @NotFound(IGNORE)
executeIgnoreTest( PersonPkjcJoinException.class, 1L );
}
@Test
public void testPkjcOneToOneJoinIgnore() {
setupTest( PersonPkjcJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonPkjcJoinIgnore.class, 1L );
}
@Test
public void testPkjcOneToOneSelectException() {
setupTest( PersonPkjcSelectException.class, 1L, false );
// optional @OneToOne @PKJC implicitly maps @NotFound(IGNORE)
executeIgnoreTest( PersonPkjcSelectException.class, 1L );
}
@Test
public void testPkjcOneToOneSelectIgnore() {
setupTest( PersonPkjcSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonPkjcSelectIgnore.class, 1L );
}
// @MapsId doesn't work in an embeddable
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getCity().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from City where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
City city = new City();
city.setId( id );
city.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setCity( city );
session.persist( person );
}
);
}
private <T extends Person> void executeIgnoreTest(Class<T> clazz, long id) {
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
checkIgnoreResult( pCheck );
pCheck.setName( "Jane Doe" );
}
);
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
assertEquals( "Jane Doe", pCheck.getName() );
checkIgnoreResult( pCheck );
pCheck.setCity( null );
}
);
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
assertEquals( "Jane Doe", pCheck.getName() );
checkIgnoreResult( pCheck );
}
);
}
private void checkIgnoreResult(Person person) {
assertNotNull( person );
assertNull( person.getCity() );
}
@MappedSuperclass
public abstract static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void setId(Long id);
public abstract City getCity();
public abstract void setCity(City city);
}
@Entity
@Table( name = "PersonOneToOneJoinIgnore" )
public static class PersonOneToOneJoinIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.JOIN )
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonOneToOneSelectIgnore" )
public static class PersonOneToOneSelectIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.SELECT )
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonManyToOneJoinIgnore" )
public static class PersonManyToOneJoinIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.JOIN )
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonManyToOneSelectIgnore" )
public static class PersonManyToOneSelectIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.SELECT )
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonPkjcJoinException" )
public static class PersonPkjcJoinException extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonPkjcJoinIgnore" )
public static class PersonPkjcJoinIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonPkjcSelectException" )
public static class PersonPkjcSelectException extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonPkjcSelectIgnore" )
public static class PersonPkjcSelectIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonMapsIdJoinIgnore" )
public static class PersonMapsIdJoinIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonMapsIdSelectIgnore" )
public static class PersonMapsIdSelectIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinIgnore" )
public static class PersonMapsIdColumnJoinIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch(FetchMode.JOIN)
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectIgnore" )
public static class PersonMapsIdColumnSelectIgnore extends Person {
@Id
private Long id;
private CityInEmbeddable cityInEmbeddable;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CityInEmbeddable getCityInEmbeddable() {
return cityInEmbeddable;
}
public void setCityInEmbeddable(CityInEmbeddable cityInEmbeddable) {
this.cityInEmbeddable = cityInEmbeddable;
}
public City getCity() {
return cityInEmbeddable == null ? null : cityInEmbeddable.getCity();
}
@Override
public void setCity(City city) {
if ( cityInEmbeddable == null ) {
cityInEmbeddable = new CityInEmbeddable();
}
cityInEmbeddable.setCity( city );
}
@Embeddable
public static class CityInEmbeddable {
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch(FetchMode.SELECT)
private City city;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
}
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Embeddable
public static class CityInEmbeddable {
}
}
}

View File

@ -0,0 +1,324 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class OptionalEagerMappedByNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonOneToOneJoinException.class,
PersonOneToOneJoinIgnore.class,
PersonOneToOneSelectException.class,
PersonOneToOneSelectIgnore.class,
Employment.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@After
public void deleteData() {
doInHibernate(
this::sessionFactory, session -> {
session.createQuery( "delete from Person" ).executeUpdate();
session.createQuery( "delete from Employment" ).executeUpdate();
}
);
}
@Test
public void testOneToOneJoinException() {
setupTest( PersonOneToOneJoinException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneJoinException.class, 1L );
checkResult( pCheck );
}
);
}
@Test
public void testOneToOneJoinIgnore() {
setupTest( PersonOneToOneJoinIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneJoinIgnore.class, 1L );
checkResult( pCheck );
}
);
}
@Test
public void testOneToOneSelectException() {
setupTest( PersonOneToOneSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectException.class, 1L );
checkResult( pCheck );
}
);
}
@Test
public void testOneToOneSelectIgnore() {
setupTest( PersonOneToOneSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectIgnore.class, 1L );
checkResult( pCheck );
}
);
}
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getEmployment().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from Employment where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
Employment employment = new Employment();
employment.setId( id );
employment.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setEmployment( employment );
employment.setPerson( person );
session.persist( person );
}
);
}
private void checkResult(Person person) {
assertNotNull( person );
assertNull( person.getEmployment() );
}
@Entity(name = "Person")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract static class Person {
@Id
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public abstract Employment getEmployment();
public abstract void setEmployment(Employment employment);
}
@Entity
@Table( name = "PersonOneToOneJoinException" )
public static class PersonOneToOneJoinException extends Person {
@OneToOne(mappedBy = "person", cascade = CascadeType.PERSIST)
@NotFound(action = NotFoundAction.EXCEPTION)
@Fetch( FetchMode.JOIN )
private Employment employment;
public Employment getEmployment() {
return employment;
}
@Override
public void setEmployment(Employment employment) {
this.employment = employment;
}
}
@Entity
@Table( name = "PersonOneToOneJoinIgnore" )
public static class PersonOneToOneJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(mappedBy = "person", cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@Fetch( FetchMode.JOIN )
private Employment employment;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Employment getEmployment() {
return employment;
}
@Override
public void setEmployment(Employment employment) {
this.employment = employment;
}
}
@Entity
@Table( name = "PersonOneToOneSelectException" )
public static class PersonOneToOneSelectException extends Person {
@Id
private Long id;
@OneToOne(mappedBy = "person", cascade = CascadeType.PERSIST)
@NotFound(action = NotFoundAction.EXCEPTION)
@Fetch( FetchMode.SELECT )
private Employment employment;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Employment getEmployment() {
return employment;
}
@Override
public void setEmployment(Employment employment) {
this.employment = employment;
}
}
@Entity
@Table( name = "PersonOneToOneSelectIgnore" )
public static class PersonOneToOneSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(mappedBy = "person", cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@Fetch( FetchMode.SELECT )
private Employment employment;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Employment getEmployment() {
return employment;
}
@Override
public void setEmployment(Employment employment) {
this.employment = employment;
}
}
@Entity(name = "Employment")
public static class Employment implements Serializable {
@Id
private Long id;
private String name;
@OneToOne
//@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Person person;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
}

View File

@ -0,0 +1,619 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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 static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class OptionalEagerNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonManyToOneJoinIgnore.class,
PersonManyToOneSelectIgnore.class,
PersonOneToOneJoinIgnore.class,
PersonOneToOneSelectIgnore.class,
PersonMapsIdJoinIgnore.class,
PersonMapsIdSelectIgnore.class,
PersonPkjcJoinException.class,
PersonPkjcJoinIgnore.class,
PersonPkjcSelectException.class,
PersonPkjcSelectIgnore.class,
PersonMapsIdColumnJoinIgnore.class,
PersonMapsIdColumnSelectIgnore.class,
City.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@Test
public void testOneToOneJoinIgnore() {
setupTest( PersonOneToOneJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonOneToOneJoinIgnore.class, 1L );
}
@Test
public void testOneToOneSelectIgnore() {
setupTest( PersonOneToOneSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonOneToOneSelectIgnore.class, 1L );
}
@Test
public void testManyToOneJoinIgnore() {
setupTest( PersonManyToOneJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonManyToOneJoinIgnore.class, 1L );
}
@Test
public void testManyToOneSelectIgnore() {
setupTest( PersonManyToOneSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonManyToOneSelectIgnore.class, 1L );
}
@Test
public void testPkjcOneToOneJoinException() {
setupTest( PersonPkjcJoinException.class, 1L, false );
// optional @OneToOne @PKJC implicitly maps @NotFound(IGNORE)
executeIgnoreTest( PersonPkjcJoinException.class, 1L );
}
@Test
public void testPkjcOneToOneJoinIgnore() {
setupTest( PersonPkjcJoinIgnore.class, 1L, false );
executeIgnoreTest( PersonPkjcJoinIgnore.class, 1L );
}
@Test
public void testPkjcOneToOneSelectException() {
setupTest( PersonPkjcSelectException.class, 1L, false );
// optional @OneToOne @PKJC implicitly maps @NotFound(IGNORE)
executeIgnoreTest( PersonPkjcSelectException.class, 1L );
}
@Test
public void testPkjcOneToOneSelectIgnore() {
setupTest( PersonPkjcSelectIgnore.class, 1L, false );
executeIgnoreTest( PersonPkjcSelectIgnore.class, 1L );
}
@Test
public void testMapsIdOneToOneJoinIgnore() {
setupTest( PersonMapsIdJoinIgnore.class, 1L, true );
executeIgnoreTest( PersonMapsIdJoinIgnore.class, 1L );
}
@Test
public void testMapsIdOneToOneSelectIgnore() {
setupTest( PersonMapsIdSelectIgnore.class, 1L, true );
executeIgnoreTest( PersonMapsIdSelectIgnore.class, 1L );
}
@Test
public void testMapsIdJoinColumnOneToOneJoinIgnore() {
setupTest( PersonMapsIdColumnJoinIgnore.class, 1L, true );
executeIgnoreTest( PersonMapsIdColumnJoinIgnore.class, 1L );
}
@Test
public void testMapsIdJoinColumnOneToOneSelectIgnore() {
setupTest( PersonMapsIdColumnSelectIgnore.class, 1L, true );
executeIgnoreTest( PersonMapsIdColumnSelectIgnore.class, 1L );
}
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getCity().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from City where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
City city = new City();
city.setId( id );
city.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setCity( city );
session.persist( person );
}
);
}
private <T extends Person> void executeIgnoreTest(Class<T> clazz, long id) {
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
checkResult( pCheck );
pCheck.setName( "Jane Doe" );
}
);
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
assertEquals( "Jane Doe", pCheck.getName() );
checkResult( pCheck );
pCheck.setCity( null );
}
);
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( clazz, id );
assertEquals( "Jane Doe", pCheck.getName() );
checkResult( pCheck );
}
);
}
private void checkResult(Person person) {
assertNotNull( person );
assertNull( person.getCity() );
}
@MappedSuperclass
public abstract static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void setId(Long id);
public abstract City getCity();
public abstract void setCity(City city);
}
@Entity
@Table( name = "PersonOneToOneJoinIgnore" )
public static class PersonOneToOneJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonOneToOneSelectIgnore" )
public static class PersonOneToOneSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneJoinIgnore" )
public static class PersonManyToOneJoinIgnore extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectIgnore" )
public static class PersonManyToOneSelectIgnore extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcJoinException" )
public static class PersonPkjcJoinException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcJoinIgnore" )
public static class PersonPkjcJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectException" )
public static class PersonPkjcSelectException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectIgnore" )
public static class PersonPkjcSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinIgnore" )
public static class PersonMapsIdJoinIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectIgnore" )
public static class PersonMapsIdSelectIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinIgnore" )
public static class PersonMapsIdColumnJoinIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch(FetchMode.JOIN)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectIgnore" )
public static class PersonMapsIdColumnSelectIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch(FetchMode.SELECT)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@ -0,0 +1,978 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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 static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class OptionalEagerRefNonPKNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonManyToOneJoinIgnore.class,
PersonManyToOneSelectIgnore.class,
PersonOneToOneJoinIgnore.class,
PersonOneToOneSelectIgnore.class,
PersonMapsIdJoinIgnore.class,
PersonMapsIdSelectIgnore.class,
PersonPkjcJoinException.class,
PersonPkjcJoinIgnore.class,
PersonPkjcSelectException.class,
PersonPkjcSelectIgnore.class,
PersonMapsIdColumnJoinIgnore.class,
PersonMapsIdColumnSelectIgnore.class,
City.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@Test
public void testOneToOneJoinIgnore() {
setupTest( PersonOneToOneJoinIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneJoinIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
@Test
public void testOneToOneSelectIgnore() {
setupTest( PersonOneToOneSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
@Test
public void testManyToOneJoinIgnore() {
setupTest( PersonManyToOneJoinIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonManyToOneJoinIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
@Test
public void testManyToOneSelectIgnore() {
setupTest( PersonManyToOneSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonManyToOneSelectIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
@Test
public void testPkjcOneToOneJoinException() {
setupTest( PersonPkjcJoinException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcJoinException.class, 1L );
// @OneToOne @PrimaryKeyJoinColumn always assumes @NotFound(IGNORE)
checkIgnore( pCheck );
}
);
}
@Test
public void testPkjcOneToOneJoinIgnore() {
setupTest( PersonPkjcJoinIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcJoinIgnore.class, 1L );
// Person is non-null and association is null.
checkIgnore( pCheck );
}
);
}
@Test
public void testPkjcOneToOneSelectException() {
setupTest( PersonPkjcSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcSelectException.class, 1L );
// @OneToOne @PrimaryKeyJoinColumn always assumes @NotFound(IGNORE)
checkIgnore( pCheck );
}
);
}
@Test
public void testPkjcOneToOneSelectIgnore() {
setupTest( PersonPkjcSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcSelectIgnore.class, 1L );
// Person is non-null and association is null.
checkIgnore( pCheck );
}
);
}
@Test
public void testMapsIdOneToOneJoinIgnore() {
setupTest( PersonMapsIdJoinIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdJoinIgnore.class, 1L );
// Person is non-null association is null.
checkIgnore( pCheck );
}
);
}
@Test
public void testMapsIdOneToOneSelectIgnore() {
setupTest( PersonMapsIdSelectIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdSelectIgnore.class, 1L );
// Person is non-null association is null.
checkIgnore( pCheck );
}
);
}
@Test
public void testMapsIdJoinColumnOneToOneJoinIgnore() {
setupTest( PersonMapsIdColumnJoinIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdColumnJoinIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
@Test
public void testMapsIdJoinColumnOneToOneSelectIgnore() {
setupTest( PersonMapsIdColumnSelectIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdColumnSelectIgnore.class, 1L );
checkIgnore( pCheck );
}
);
}
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getCity().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from City where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
City city = new City();
city.setId( id );
city.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setCity( city );
session.persist( person );
}
);
}
private void checkIgnore(Person person) {
assertNotNull( person );
assertNull( person.getCity() );
}
private void checkException(Person person) {
assertNull( person );
}
@MappedSuperclass
public abstract static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void setId(Long id);
public abstract City getCity();
public abstract void setCity(City city);
}
@Entity
@Table( name = "PersonOneToOneJoinException" )
public static class PersonOneToOneJoinException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonOneToOneJoinIgnore" )
public static class PersonOneToOneJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonOneToOneSelectException" )
public static class PersonOneToOneSelectException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonOneToOneSelectIgnore" )
public static class PersonOneToOneSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneJoinException" )
public static class PersonManyToOneJoinException extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneJoinIgnore" )
public static class PersonManyToOneJoinIgnore extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.JOIN )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectException" )
public static class PersonManyToOneSelectException extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectIgnore" )
public static class PersonManyToOneSelectIgnore extends Person {
@Id
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch( FetchMode.SELECT )
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcJoinException" )
public static class PersonPkjcJoinException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.JOIN )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcJoinIgnore" )
public static class PersonPkjcJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectException" )
public static class PersonPkjcSelectException extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@Fetch(FetchMode.SELECT )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectIgnore" )
public static class PersonPkjcSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinException" )
public static class PersonMapsIdJoinException extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@Fetch(FetchMode.JOIN )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinIgnore" )
public static class PersonMapsIdJoinIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.JOIN )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectException" )
public static class PersonMapsIdSelectException extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@Fetch(FetchMode.SELECT )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectIgnore" )
public static class PersonMapsIdSelectIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@Fetch(FetchMode.SELECT )
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinException" )
public static class PersonMapsIdColumnJoinException extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch(FetchMode.JOIN)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinIgnore" )
public static class PersonMapsIdColumnJoinIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch(FetchMode.JOIN)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectException" )
public static class PersonMapsIdColumnSelectException extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch(FetchMode.SELECT)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectIgnore" )
public static class PersonMapsIdColumnSelectIgnore extends Person {
@Id
private Long id;
@OneToOne
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(
name = "cityName",
referencedColumnName = "name",
foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)
)
@Fetch(FetchMode.SELECT)
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@ -0,0 +1,723 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.Hibernate;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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 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;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class OptionalLazyNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonManyToOneSelectException.class,
PersonManyToOneSelectIgnore.class,
PersonOneToOneSelectException.class,
PersonOneToOneSelectIgnore.class,
PersonMapsIdSelectException.class,
PersonMapsIdSelectIgnore.class,
PersonPkjcSelectException.class,
PersonPkjcSelectIgnore.class,
PersonMapsIdColumnSelectIgnore.class,
PersonMapsIdColumnSelectException.class,
City.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@Test
public void testOneToOneSelectException() {
setupTest( PersonOneToOneSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testOneToOneSelectIgnore() {
setupTest( PersonOneToOneSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectIgnore.class, 1L );
assertNotNull( pCheck );
assertNull( pCheck.getCity() );
}
);
}
@Test
public void testManyToOneSelectException() {
setupTest( PersonManyToOneSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonManyToOneSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testManyToOneSelectIgnore() {
setupTest( PersonManyToOneSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonManyToOneSelectIgnore.class, 1L );
assertNotNull( pCheck );
assertNull( pCheck.getCity() );
}
);
}
@Test
public void testPkjcOneToOneSelectException() {
setupTest( PersonPkjcSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcSelectException.class, 1L );
assertNotNull( pCheck );
// eagerly loaded because @PKJC assumes ignoreNotFound
assertTrue( Hibernate.isInitialized( pCheck.getCity() ) );
assertNull( pCheck.getCity() );
/*
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
*/
}
);
}
@Test
public void testPkjcOneToOneSelectIgnore() {
setupTest( PersonPkjcSelectIgnore.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcSelectIgnore.class, 1L );
// Person is non-null and association is null.
assertNotNull( pCheck );
assertNull( pCheck.getCity() );
}
);
}
@Test
public void testMapsIdOneToOneSelectException() {
setupTest( PersonMapsIdSelectException.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testMapsIdOneToOneSelectIgnore() {
setupTest( PersonMapsIdSelectIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdSelectIgnore.class, 1L );
// Person is non-null association is null.
assertNotNull( pCheck );
assertNull( pCheck.getCity() );
}
);
}
@Test
public void testMapsIdJoinColumnOneToOneSelectException() {
setupTest( PersonMapsIdColumnSelectException.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdColumnSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testMapsIdJoinColumnOneToOneSelectIgnore() {
setupTest( PersonMapsIdColumnSelectIgnore.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdColumnSelectIgnore.class, 1L );
// Person should be non-null;association should be null.
assertNotNull( pCheck );
assertNull( pCheck.getCity() );
}
);
}
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getCity().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from City where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
City city = new City();
city.setId( id );
city.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setCity( city );
session.persist( person );
}
);
}
@MappedSuperclass
public abstract static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void setId(Long id);
public abstract City getCity();
public abstract void setCity(City city);
}
@Entity
@Table( name = "PersonOneToOneSelectException" )
public static class PersonOneToOneSelectException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonOneToOneSelectIgnore" )
public static class PersonOneToOneSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectException" )
public static class PersonManyToOneSelectException extends Person {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectIgnore" )
public static class PersonManyToOneSelectIgnore extends Person {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectException" )
public static class PersonPkjcSelectException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectIgnore" )
public static class PersonPkjcSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinException" )
public static class PersonMapsIdJoinException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinIgnore" )
public static class PersonMapsIdJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectException" )
public static class PersonMapsIdSelectException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectIgnore" )
public static class PersonMapsIdSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinException" )
public static class PersonMapsIdColumnJoinException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinIgnore" )
public static class PersonMapsIdColumnJoinIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectException" )
public static class PersonMapsIdColumnSelectException extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectIgnore" )
public static class PersonMapsIdColumnSelectIgnore extends Person {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@ -0,0 +1,442 @@
package org.hibernate.test.notfound;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.Hibernate;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
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 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;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-12436")
public class RequiredLazyNotFoundTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
PersonManyToOneSelectException.class,
PersonOneToOneSelectException.class,
PersonMapsIdSelectException.class,
PersonPkjcSelectException.class,
PersonMapsIdColumnSelectException.class,
City.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
}
@Test
public void testOneToOneSelectException() {
setupTest( PersonOneToOneSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonOneToOneSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testManyToOneSelectException() {
setupTest( PersonManyToOneSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonManyToOneSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testPkjcOneToOneSelectException() {
setupTest( PersonPkjcSelectException.class, 1L, false );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonPkjcSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testMapsIdOneToOneSelectException() {
setupTest( PersonMapsIdSelectException.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
@Test
public void testMapsIdJoinColumnOneToOneSelectException() {
setupTest( PersonMapsIdColumnSelectException.class, 1L, true );
doInHibernate(
this::sessionFactory, session -> {
Person pCheck = session.find( PersonMapsIdColumnSelectException.class, 1L );
assertNotNull( pCheck );
assertFalse( Hibernate.isInitialized( pCheck.getCity() ) );
try {
Hibernate.initialize( pCheck.getCity() );
fail( "Should have thrown ObjectNotFoundException" );
}
catch (ObjectNotFoundException expected) {
session.getTransaction().setRollbackOnly();
}
}
);
}
private <T extends Person> void setupTest(Class<T> clazz, long id, boolean isMapsId ) {
persistData( clazz, id, isMapsId );
doInHibernate(
this::sessionFactory, session -> {
Person p = session.find( clazz, id );
assertEquals( "New York", p.getCity().getName() );
}
);
doInHibernate(
this::sessionFactory, session -> {
session.createNativeQuery( "delete from City where id = " + id )
.executeUpdate();
}
);
}
private <T extends Person> void persistData(Class<T> clazz, long id, boolean isMapsId) {
final Person person;
try {
person = clazz.newInstance();
}
catch (Exception ex) {
throw new RuntimeException( ex );
}
doInHibernate(
this::sessionFactory, session -> {
City city = new City();
city.setId( id );
city.setName( "New York" );
if ( !isMapsId ) {
person.setId( id );
}
person.setName( "John Doe" );
person.setCity( city );
session.persist( person );
}
);
}
@MappedSuperclass
public abstract static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void setId(Long id);
public abstract City getCity();
public abstract void setCity(City city);
}
@Entity
@Table( name = "PersonOneToOneSelectException" )
public static class PersonOneToOneSelectException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonManyToOneSelectException" )
public static class PersonManyToOneSelectException extends Person {
@Id
private Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonPkjcSelectException" )
public static class PersonPkjcSelectException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@PrimaryKeyJoinColumn
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdJoinException" )
public static class PersonMapsIdJoinException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@MapsId
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdSelectException" )
public static class PersonMapsIdSelectException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@MapsId
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnJoinException" )
public static class PersonMapsIdColumnJoinException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "PersonMapsIdColumnSelectException" )
public static class PersonMapsIdColumnSelectException extends Person {
@Id
private Long id;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "fk", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private City city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public City getCity() {
return city;
}
@Override
public void setCity(City city) {
this.city = city;
}
}
@Entity
@Table( name = "City" )
public static class City implements Serializable {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@ -0,0 +1,129 @@
/*
* 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.ops;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertNotNull;
/**
*
* @author localEvg
*/
@TestForIssue( jiraKey = "HHH-12436" )
public class OneToOneMergeTest extends BaseEntityManagerFunctionalTestCase {
@Override
public Class<?>[] getAnnotatedClasses() {
return new Class[]{
Prima.class,
Secunda.class
};
}
@Test
public void testMerge() throws Exception {
Long primaId = doInJPA( this::entityManagerFactory, entityManager -> {
Prima prima = new Prima();
prima.setOptionalData(null);
entityManager.persist(prima);
return prima.getId();
} );
assertNotNull(primaId);
doInJPA( this::entityManagerFactory, entityManager -> {
Prima prima = entityManager.find( Prima.class, primaId );
Secunda sec = new Secunda();
sec.setParent(prima);
prima.setOptionalData(sec);
Prima mergedPrima = entityManager.merge(prima);
assertNotNull(mergedPrima);
} );
}
@Entity(name = "Prima")
public static class Prima implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
//@PrimaryKeyJoinColumn
@OneToOne(mappedBy = "parent", optional = true , cascade = CascadeType.ALL)
private Secunda optionalData;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Secunda getOptionalData() {
return optionalData;
}
public void setOptionalData(Secunda optionalData) {
this.optionalData = optionalData;
}
}
@Entity(name = "Secunda")
public static class Secunda implements Serializable {
@Id
@Column(name = "id", nullable = false)
private Long id;
@MapsId
@OneToOne(optional = false)
@JoinColumn(name = "id", nullable = false)
private Prima parent;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Prima getParent() {
return parent;
}
public void setParent(Prima parent) {
this.parent = parent;
}
}
}