-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HHH-14103 : Add test cases showing that an entity's transient attribu…
…te can be overridden to be persistent in entity subclasses (cherry picked from commit fb40f8e)
- Loading branch information
Showing
4 changed files
with
1,514 additions
and
0 deletions.
There are no files selected for viewing
380 changes: 380 additions & 0 deletions
380
...ore/src/test/java/org/hibernate/test/inheritance/TransientOverrideAsPersistentJoined.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,380 @@ | ||
/* | ||
* 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.inheritance; | ||
|
||
import java.util.List; | ||
import javax.persistence.Column; | ||
import javax.persistence.ConstraintMode; | ||
import javax.persistence.DiscriminatorColumn; | ||
import javax.persistence.Entity; | ||
import javax.persistence.ForeignKey; | ||
import javax.persistence.Id; | ||
import javax.persistence.Inheritance; | ||
import javax.persistence.InheritanceType; | ||
import javax.persistence.JoinColumn; | ||
import javax.persistence.ManyToOne; | ||
import javax.persistence.OneToOne; | ||
import javax.persistence.Table; | ||
import javax.persistence.Transient; | ||
import javax.persistence.criteria.CriteriaBuilder; | ||
import javax.persistence.criteria.CriteriaQuery; | ||
import javax.persistence.criteria.ParameterExpression; | ||
import javax.persistence.criteria.Predicate; | ||
import javax.persistence.criteria.Root; | ||
|
||
import org.hibernate.testing.FailureExpected; | ||
import org.hibernate.testing.TestForIssue; | ||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
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.assertSame; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
@TestForIssue(jiraKey = "HHH-14103") | ||
public class TransientOverrideAsPersistentJoined extends BaseNonConfigCoreFunctionalTestCase { | ||
|
||
@Test | ||
public void testFindByRootClass() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final Employee editor = session.find( Employee.class, "Jane Smith" ); | ||
assertNotNull( editor ); | ||
assertEquals( "Senior Editor", editor.getTitle() ); | ||
final Employee writer = session.find( Employee.class, "John Smith" ); | ||
assertTrue( Writer.class.isInstance( writer ) ); | ||
assertEquals( "Writing", writer.getTitle() ); | ||
assertNotNull( ( (Writer) writer ).getGroup() ); | ||
final Group group = ( (Writer) writer ).getGroup(); | ||
assertEquals( writer.getTitle(), group.getName() ); | ||
final Job jobEditor = session.find( Job.class, "Edit" ); | ||
assertSame( editor, jobEditor.getEmployee() ); | ||
final Job jobWriter = session.find( Job.class, "Write" ); | ||
assertSame( writer, jobWriter.getEmployee() ); | ||
}); | ||
} | ||
|
||
@Test | ||
public void testFindBySubclass() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final Editor editor = session.find( Editor.class, "Jane Smith" ); | ||
assertNotNull( editor ); | ||
assertEquals( "Senior Editor", editor.getTitle() ); | ||
final Writer writer = session.find( Writer.class, "John Smith" ); | ||
assertEquals( "Writing", writer.getTitle() ); | ||
assertNotNull( writer.getGroup() ); | ||
final Group group = writer.getGroup(); | ||
assertEquals( writer.getTitle(), group.getName() ); | ||
final Job jobEditor = session.find( Job.class, "Edit" ); | ||
assertSame( editor, jobEditor.getEmployee() ); | ||
final Job jobWriter = session.find( Job.class, "Write" ); | ||
assertSame( writer, jobWriter.getEmployee() ); | ||
}); | ||
} | ||
|
||
@Test | ||
public void testQueryByRootClass() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final List<Employee> employees = session.createQuery( "from Employee", Employee.class ) | ||
.getResultList(); | ||
assertEquals( 2, employees.size() ); | ||
assertTrue( Editor.class.isInstance( employees.get( 0 ) ) ); | ||
assertTrue( Writer.class.isInstance( employees.get( 1 ) ) ); | ||
final Editor editor = (Editor) employees.get( 0 ); | ||
assertEquals( "Senior Editor", editor.getTitle() ); | ||
final Writer writer = (Writer) employees.get( 1 ); | ||
assertEquals( "Writing", writer.getTitle() ); | ||
assertNotNull( writer.getGroup() ); | ||
final Group group = writer.getGroup(); | ||
assertEquals( writer.getTitle(), group.getName() ); | ||
}); | ||
} | ||
|
||
@Test | ||
@FailureExpected( jiraKey = "HHH-12981") | ||
public void testQueryByRootClassAndOverridenProperty() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final Employee editor = session.createQuery( "from Employee where title=:title", Employee.class ) | ||
.setParameter( "title", "Senior Editor" ) | ||
.getSingleResult(); | ||
assertTrue( Editor.class.isInstance( editor ) ); | ||
|
||
final Employee writer = session.createQuery( "from Employee where title=:title", Employee.class ) | ||
.setParameter( "title", "Writing" ) | ||
.getSingleResult(); | ||
assertTrue( Writer.class.isInstance( writer ) ); | ||
assertNotNull( ( (Writer) writer ).getGroup() ); | ||
assertEquals( writer.getTitle(), ( (Writer) writer ).getGroup() .getName() ); | ||
}); | ||
} | ||
|
||
@Test | ||
@FailureExpected( jiraKey = "HHH-12981") | ||
public void testQueryByRootClassAndOverridenPropertyTreat() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final Employee editor = session.createQuery( "from Employee e where treat( e as Editor ).title=:title", Employee.class ) | ||
.setParameter( "title", "Senior Editor" ) | ||
.getSingleResult(); | ||
assertTrue( Editor.class.isInstance( editor ) ); | ||
|
||
final Employee writer = session.createQuery( "from Employee e where treat( e as Writer).title=:title", Employee.class ) | ||
.setParameter( "title", "Writing" ) | ||
.getSingleResult(); | ||
assertTrue( Writer.class.isInstance( writer ) ); | ||
assertNotNull( ( (Writer) writer ).getGroup() ); | ||
assertEquals( writer.getTitle(), ( (Writer) writer ).getGroup() .getName() ); | ||
}); | ||
} | ||
|
||
@Test | ||
public void testQueryBySublassAndOverridenProperty() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
final Editor editor = session.createQuery( "from Editor where title=:title", Editor.class ) | ||
.setParameter( "title", "Senior Editor" ) | ||
.getSingleResult(); | ||
assertTrue( Editor.class.isInstance( editor ) ); | ||
|
||
final Writer writer = session.createQuery( "from Writer where title=:title", Writer.class ) | ||
.setParameter( "title", "Writing" ) | ||
.getSingleResult(); | ||
assertNotNull( writer.getGroup() ); | ||
assertEquals( writer.getTitle(), writer.getGroup().getName() ); | ||
}); | ||
} | ||
|
||
@Test | ||
@FailureExpected( jiraKey = "HHH-12981") | ||
public void testCriteriaQueryByRootClassAndOverridenProperty() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
|
||
final CriteriaBuilder builder = session.getCriteriaBuilder(); | ||
|
||
final CriteriaQuery<Employee> query = builder.createQuery( Employee.class ); | ||
final Root<Employee> root = query.from( Employee.class ); | ||
final ParameterExpression<String> parameter = builder.parameter( String.class, "title" ); | ||
|
||
final Predicate predicateEditor = builder.equal( | ||
builder.treat( root, Editor.class ).get( "title" ), | ||
parameter | ||
); | ||
query.where( predicateEditor ); | ||
final Employee editor = session.createQuery( query ) | ||
.setParameter( "title", "Senior Editor" ) | ||
.getSingleResult(); | ||
assertTrue( Editor.class.isInstance( editor ) ); | ||
|
||
final Predicate predicateWriter = builder.equal( | ||
builder.treat( root, Writer.class ).get( "title" ), | ||
parameter | ||
); | ||
query.where( predicateWriter ); | ||
final Employee writer = session.createQuery( query ) | ||
.setParameter( "title", "Writing" ) | ||
.getSingleResult(); | ||
assertTrue( Writer.class.isInstance( writer ) ); | ||
assertNotNull( ( (Writer) writer ).getGroup() ); | ||
assertEquals( writer.getTitle(), ( (Writer) writer ).getGroup() .getName() ); | ||
}); | ||
} | ||
|
||
@Before | ||
public void setupData() { | ||
|
||
doInHibernate( this::sessionFactory, session -> { | ||
Job jobEditor = new Job("Edit"); | ||
jobEditor.setEmployee(new Editor("Jane Smith", "Senior Editor")); | ||
Job jobWriter= new Job("Write"); | ||
jobWriter.setEmployee(new Writer("John Smith", new Group("Writing"))); | ||
|
||
Employee editor = jobEditor.getEmployee(); | ||
Employee writer = jobWriter.getEmployee(); | ||
Group group = Writer.class.cast( writer ).getGroup(); | ||
|
||
session.persist( editor ); | ||
session.persist( group ); | ||
session.persist( writer ); | ||
session.persist( jobEditor ); | ||
session.persist( jobWriter ); | ||
}); | ||
} | ||
|
||
@After | ||
public void cleanupData() { | ||
doInHibernate( this::sessionFactory, session -> { | ||
session.createQuery( "delete from Job" ).executeUpdate(); | ||
session.createQuery( "delete from Employee" ).executeUpdate(); | ||
session.createQuery( "delete from Group" ).executeUpdate(); | ||
}); | ||
} | ||
|
||
@Override | ||
protected Class<?>[] getAnnotatedClasses() { | ||
return new Class<?>[] { | ||
Employee.class, | ||
Editor.class, | ||
Writer.class, | ||
Group.class, | ||
Job.class | ||
}; | ||
} | ||
|
||
@Entity(name="Employee") | ||
@Inheritance(strategy = InheritanceType.JOINED) | ||
@DiscriminatorColumn(name="department") | ||
public static abstract class Employee { | ||
private String name; | ||
private String title; | ||
|
||
protected Employee(String name) { | ||
this(); | ||
setName(name); | ||
} | ||
|
||
@Id | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Transient | ||
public String getTitle() { | ||
return title; | ||
} | ||
|
||
protected Employee() { | ||
// this form used by Hibernate | ||
} | ||
|
||
protected void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
protected void setTitle(String title) { | ||
this.title = title; | ||
} | ||
} | ||
|
||
@Entity(name = "Editor") | ||
public static class Editor extends Employee { | ||
public Editor(String name, String title) { | ||
super(name); | ||
setTitle( title ); | ||
} | ||
|
||
@Column(name = "e_title") | ||
public String getTitle() { | ||
return super.getTitle(); | ||
} | ||
|
||
public void setTitle(String title) { | ||
super.setTitle( title ); | ||
} | ||
|
||
protected Editor() { | ||
// this form used by Hibernate | ||
super(); | ||
} | ||
} | ||
|
||
@Entity(name = "Writer") | ||
public static class Writer extends Employee { | ||
private Group group; | ||
|
||
public Writer(String name, Group group) { | ||
super(name); | ||
setGroup(group); | ||
} | ||
|
||
// Cannot have a constraint on e_title because | ||
// Editor#title (which uses the same e_title column) can be non-null, | ||
// and there is no associated group. | ||
@ManyToOne(optional = false) | ||
@JoinColumn(name = "e_title", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) | ||
public Group getGroup() { | ||
return group; | ||
} | ||
|
||
@Column(name = "e_title", insertable = false, updatable = false) | ||
public String getTitle() { | ||
return super.getTitle(); | ||
} | ||
|
||
public void setTitle(String title) { | ||
super.setTitle( title ); | ||
} | ||
|
||
protected Writer() { | ||
// this form used by Hibernate | ||
super(); | ||
} | ||
|
||
protected void setGroup(Group group) { | ||
this.group = group; | ||
setTitle( group.getName() ); | ||
} | ||
} | ||
|
||
@Entity(name = "Group") | ||
@Table(name = "WorkGroup") | ||
public static class Group { | ||
private String name; | ||
|
||
public Group(String name) { | ||
this(); | ||
setName(name); | ||
} | ||
|
||
@Id | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
protected Group() { | ||
// this form used by Hibernate | ||
} | ||
|
||
protected void setName(String name) { | ||
this.name = name; | ||
} | ||
} | ||
|
||
@Entity(name = "Job") | ||
public static class Job { | ||
private String name; | ||
private Employee employee; | ||
|
||
public Job(String name) { | ||
this(); | ||
setName(name); | ||
} | ||
|
||
@Id | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@OneToOne | ||
@JoinColumn(name="employee_name") | ||
public Employee getEmployee() { | ||
return employee; | ||
} | ||
|
||
protected Job() { | ||
// this form used by Hibernate | ||
} | ||
|
||
protected void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
protected void setEmployee(Employee e) { | ||
this.employee = e; | ||
} | ||
} | ||
} |
Oops, something went wrong.