HHH-16191 Add test and fix checks for skipping resolving polymorphic associated entity instances
This commit is contained in:
parent
10bfcabee2
commit
8312db1b9e
|
@ -78,15 +78,15 @@ public interface Initializer {
|
|||
default boolean isAttributeAssignableToConcreteDescriptor(
|
||||
FetchParentAccess parentAccess,
|
||||
AttributeMapping referencedModelPart) {
|
||||
if ( parentAccess != null && parentAccess.isEntityInitializer() ) {
|
||||
final EntityPersister concreteDescriptor = parentAccess.findFirstEntityInitializer()
|
||||
.getConcreteDescriptor();
|
||||
final EntityInitializer entityInitializer = parentAccess == null ?
|
||||
null :
|
||||
parentAccess.findFirstEntityInitializer();
|
||||
if ( entityInitializer != null ) {
|
||||
final EntityPersister concreteDescriptor = entityInitializer.getConcreteDescriptor();
|
||||
if ( concreteDescriptor.getEntityMetamodel().isPolymorphic() ) {
|
||||
final EntityPersister declaringType = (EntityPersister) referencedModelPart.getDeclaringType();
|
||||
if ( concreteDescriptor != declaringType ) {
|
||||
if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getEntityName() ) ) {
|
||||
return false;
|
||||
}
|
||||
return declaringType.getSubclassEntityNames().contains( concreteDescriptor.getEntityName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
private EntityKey entityKey;
|
||||
private Object entityInstance;
|
||||
private Object entityInstanceForNotify;
|
||||
private boolean missing;
|
||||
protected boolean missing;
|
||||
boolean isInitialized;
|
||||
private boolean isOwningInitializer;
|
||||
private Object[] resolvedEntityState;
|
||||
|
@ -399,26 +399,44 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
}
|
||||
}
|
||||
|
||||
private boolean shouldSkipResolveInstance(RowProcessingState rowProcessingState) {
|
||||
final NavigablePath parent = navigablePath.getParent();
|
||||
if ( parent != null ) {
|
||||
final Initializer parentInitializer = rowProcessingState.resolveInitializer( parent );
|
||||
if ( parentInitializer != null && parentInitializer.isEntityInitializer() ) {
|
||||
if ( isReferencedModelPartAssignableToConcreteParent( parentInitializer ) ) {
|
||||
return true;
|
||||
protected boolean shouldSkipResolveInstance(RowProcessingState rowProcessingState) {
|
||||
if ( navigablePath.getParent() != null ) {
|
||||
Initializer parentInitializer = rowProcessingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInitializer != null ) {
|
||||
ModelPart modelPart = referencedModelPart;
|
||||
NavigablePath currentNavigablePath = navigablePath;
|
||||
// Walk back initializers until we find an EntityInitializer
|
||||
while ( parentInitializer != null && !parentInitializer.isEntityInitializer() ) {
|
||||
modelPart = parentInitializer.getInitializedPart();
|
||||
currentNavigablePath = currentNavigablePath.getParent();
|
||||
parentInitializer = rowProcessingState.resolveInitializer( currentNavigablePath.getParent() );
|
||||
}
|
||||
if ( parentInitializer != null && parentInitializer.asEntityInitializer()
|
||||
.getEntityDescriptor()
|
||||
.getEntityMetamodel()
|
||||
.isPolymorphic() ) {
|
||||
parentInitializer.resolveKey( rowProcessingState );
|
||||
return isReferencedModelPartInConcreteParent(
|
||||
modelPart,
|
||||
currentNavigablePath,
|
||||
parentInitializer
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isReferencedModelPartAssignableToConcreteParent(Initializer parentInitializer) {
|
||||
private boolean isReferencedModelPartInConcreteParent(
|
||||
ModelPart modelPart,
|
||||
NavigablePath partNavigablePath,
|
||||
Initializer parentInitializer) {
|
||||
final EntityPersister parentConcreteDescriptor = parentInitializer.asEntityInitializer()
|
||||
.getConcreteDescriptor();
|
||||
if ( parentConcreteDescriptor != null && parentConcreteDescriptor.getEntityMetamodel().isPolymorphic()) {
|
||||
final ModelPart concreteModelPart = parentConcreteDescriptor.findByPath( navigablePath.getLocalName() );
|
||||
if ( parentConcreteDescriptor != null && parentConcreteDescriptor.getEntityMetamodel().isPolymorphic() ) {
|
||||
final ModelPart concreteModelPart = parentConcreteDescriptor.findByPath( partNavigablePath.getLocalName() );
|
||||
if ( concreteModelPart == null
|
||||
|| !referencedModelPart.getJavaType().getJavaTypeClass()
|
||||
|| !modelPart.getJavaType().getJavaTypeClass()
|
||||
.isAssignableFrom( concreteModelPart.getJavaType().getJavaTypeClass() ) ) {
|
||||
/*
|
||||
Given:
|
||||
|
|
|
@ -71,6 +71,11 @@ public class EntityJoinedFetchInitializer extends AbstractEntityInitializer {
|
|||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if ( shouldSkipResolveInstance( rowProcessingState ) ) {
|
||||
missing = true;
|
||||
return;
|
||||
}
|
||||
|
||||
super.resolveKey( rowProcessingState );
|
||||
|
||||
// super processes the foreign-key target column. here we
|
||||
|
|
|
@ -67,10 +67,8 @@ public class LoadANonExistingNotFoundEntityTest extends BaseNonConfigCoreFunctio
|
|||
}
|
||||
);
|
||||
|
||||
// The Employee#employer must be initialized immediately because
|
||||
// enhanced proxies (and HibernateProxy objects) should never be created
|
||||
// for a "not found" association.
|
||||
assertEquals( 2, statistics.getPrepareStatementCount() );
|
||||
// we should get 1 query for the Employee with join
|
||||
assertEquals( 1, statistics.getPrepareStatementCount() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -86,10 +84,8 @@ public class LoadANonExistingNotFoundEntityTest extends BaseNonConfigCoreFunctio
|
|||
}
|
||||
);
|
||||
|
||||
// The Employee#employer must be initialized immediately because
|
||||
// enhanced proxies (and HibernateProxy objects) should never be created
|
||||
// for a "not found" association.
|
||||
assertEquals( 2, statistics.getPrepareStatementCount() );
|
||||
// we should get 1 query for the Employee with join
|
||||
assertEquals( 1, statistics.getPrepareStatementCount() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -178,7 +174,7 @@ public class LoadANonExistingNotFoundEntityTest extends BaseNonConfigCoreFunctio
|
|||
|
||||
private String name;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "employer_id",foreignKey = @ForeignKey(value= ConstraintMode.NO_CONSTRAINT))
|
||||
@NotFound(action=NotFoundAction.IGNORE)
|
||||
private Employer employer;
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
package org.hibernate.orm.test.inheritance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
|
@ -307,7 +303,6 @@ public class TransientOverrideAsPersistentMappedSuperclass {
|
|||
// Editor#title (which uses the same e_title column) can be non-null,
|
||||
// and there is no associated group.
|
||||
@ManyToOne(optional = false)
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
@JoinColumn(name = "e_title", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
package org.hibernate.orm.test.inheritance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
|
@ -300,7 +296,6 @@ public class TransientOverrideAsPersistentSingleTable {
|
|||
// Editor#title (which uses the same e_title column) can be non-null,
|
||||
// and there is no associated group.
|
||||
@ManyToOne(optional = false)
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
@JoinColumn(name = "e_title", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
|
|
|
@ -8,10 +8,6 @@ package org.hibernate.orm.test.inheritance;
|
|||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
|
@ -303,7 +299,6 @@ public class TransientOverrideAsPersistentTablePerClass {
|
|||
// Editor#title (which uses the same e_title column) can be non-null,
|
||||
// and there is no associated group.
|
||||
@ManyToOne(optional = false)
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
@JoinColumn(name = "e_title", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
public Group getGroup() {
|
||||
return group;
|
||||
|
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* 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.orm.test.inheritance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.ParameterExpression;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-14103")
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
TransientOverrideAsPersistentWithEmbeddable.Employee.class,
|
||||
TransientOverrideAsPersistentWithEmbeddable.Editor.class,
|
||||
TransientOverrideAsPersistentWithEmbeddable.Writer.class,
|
||||
TransientOverrideAsPersistentWithEmbeddable.Group.class,
|
||||
TransientOverrideAsPersistentWithEmbeddable.Job.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class TransientOverrideAsPersistentWithEmbeddable {
|
||||
|
||||
@Test
|
||||
public void testFindByRootClass(SessionFactoryScope scope) {
|
||||
scope.inTransaction( 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" );
|
||||
assertThat( writer, instanceOf( Writer.class ) );
|
||||
assertEquals( "Writing", writer.getTitle() );
|
||||
assertNotNull( ( (Writer) writer ).getWriterEmbeddable().getGroup() );
|
||||
final Group group = ( (Writer) writer ).getWriterEmbeddable().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(SessionFactoryScope scope) {
|
||||
scope.inTransaction( 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.getWriterEmbeddable().getGroup() );
|
||||
final Group group = writer.getWriterEmbeddable().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(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final List<Employee> employees = session.createQuery( "from Employee", Employee.class )
|
||||
.getResultList();
|
||||
assertEquals( 2, employees.size() );
|
||||
assertThat( employees.get( 0 ), instanceOf( Editor.class ) );
|
||||
assertThat( employees.get( 1 ), instanceOf( Writer.class ) );
|
||||
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.getWriterEmbeddable().getGroup() );
|
||||
final Group group = writer.getWriterEmbeddable().getGroup();
|
||||
assertEquals( writer.getTitle(), group.getName() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryByRootClassAndOverridenProperty(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final Employee editor = session.createQuery( "from Employee where title=:title", Employee.class )
|
||||
.setParameter( "title", "Senior Editor" )
|
||||
.getSingleResult();
|
||||
assertThat( editor, instanceOf( Editor.class ) );
|
||||
|
||||
final Employee writer = session.createQuery( "from Employee where title=:title", Employee.class )
|
||||
.setParameter( "title", "Writing" )
|
||||
.getSingleResult();
|
||||
assertThat( writer, instanceOf( Writer.class ) );
|
||||
assertNotNull( ( (Writer) writer ).getWriterEmbeddable().getGroup() );
|
||||
assertEquals( writer.getTitle(), ( (Writer) writer ).getWriterEmbeddable().getGroup().getName() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryByRootClassAndOverridenPropertyTreat(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final Employee editor = session.createQuery(
|
||||
"from Employee e where treat( e as Editor ).title=:title",
|
||||
Employee.class
|
||||
)
|
||||
.setParameter( "title", "Senior Editor" )
|
||||
.getSingleResult();
|
||||
assertThat( editor, instanceOf( Editor.class ) );
|
||||
|
||||
final Employee writer = session.createQuery(
|
||||
"from Employee e where treat( e as Writer).title=:title",
|
||||
Employee.class
|
||||
)
|
||||
.setParameter( "title", "Writing" )
|
||||
.getSingleResult();
|
||||
assertThat( writer, instanceOf( Writer.class ) );
|
||||
assertNotNull( ( (Writer) writer ).getWriterEmbeddable().getGroup() );
|
||||
assertEquals( writer.getTitle(), ( (Writer) writer ).getWriterEmbeddable().getGroup().getName() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryBySublassAndOverridenProperty(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final Editor editor = session.createQuery( "from Editor where title=:title", Editor.class )
|
||||
.setParameter( "title", "Senior Editor" )
|
||||
.getSingleResult();
|
||||
assertThat( editor, instanceOf( Editor.class ) );
|
||||
|
||||
final Writer writer = session.createQuery( "from Writer where title=:title", Writer.class )
|
||||
.setParameter( "title", "Writing" )
|
||||
.getSingleResult();
|
||||
assertNotNull( writer.getWriterEmbeddable().getGroup() );
|
||||
assertEquals( writer.getTitle(), writer.getWriterEmbeddable().getGroup().getName() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCriteriaQueryByRootClassAndOverridenProperty(SessionFactoryScope scope) {
|
||||
scope.inTransaction( 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();
|
||||
assertThat( editor, instanceOf( Editor.class ) );
|
||||
|
||||
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();
|
||||
assertThat( writer, instanceOf( Writer.class ) );
|
||||
assertNotNull( ( (Writer) writer ).getWriterEmbeddable().getGroup() );
|
||||
assertEquals( writer.getTitle(), ( (Writer) writer ).getWriterEmbeddable().getGroup().getName() );
|
||||
} );
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setupData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( 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 ).getWriterEmbeddable().getGroup();
|
||||
|
||||
session.persist( editor );
|
||||
session.persist( group );
|
||||
session.persist( writer );
|
||||
session.persist( jobEditor );
|
||||
session.persist( jobWriter );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanupData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
session.createQuery( "delete from Job" ).executeUpdate();
|
||||
session.createQuery( "delete from Employee" ).executeUpdate();
|
||||
session.createQuery( "delete from Group" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
|
||||
@MappedSuperclass
|
||||
public static class AbstractEmployee {
|
||||
private String title;
|
||||
|
||||
@Transient
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
protected void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Employee")
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
@DiscriminatorColumn(name = "department")
|
||||
public static abstract class Employee extends AbstractEmployee {
|
||||
private String name;
|
||||
|
||||
protected Employee(String name) {
|
||||
this();
|
||||
setName( name );
|
||||
}
|
||||
|
||||
@Id
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
protected Employee() {
|
||||
// this form used by Hibernate
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class WriterEmbeddable {
|
||||
private Group 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;
|
||||
}
|
||||
|
||||
public void setGroup(Group group) {
|
||||
this.group = group;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Writer")
|
||||
public static class Writer extends Employee {
|
||||
private WriterEmbeddable writerEmbeddable;
|
||||
|
||||
public Writer(String name, Group group) {
|
||||
super( name );
|
||||
this.writerEmbeddable = new WriterEmbeddable();
|
||||
setGroup( 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.writerEmbeddable.setGroup( group );
|
||||
setTitle( group.getName() );
|
||||
}
|
||||
|
||||
public WriterEmbeddable getWriterEmbeddable() {
|
||||
return writerEmbeddable;
|
||||
}
|
||||
|
||||
public void setWriterEmbeddable(WriterEmbeddable writerEmbeddable) {
|
||||
this.writerEmbeddable = writerEmbeddable;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Group")
|
||||
@Table(name = "WorkGroup")
|
||||
public static class Group {
|
||||
private String name;
|
||||
|
||||
private String desctiption;
|
||||
|
||||
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;
|
||||
|
||||
private String description;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue