返回其他子类对象的JPA EntityManager finder方法
我面临JPA EntityManager finder方法的问题。JPA实体使用的继承结构如下:返回其他子类对象的JPA EntityManager finder方法,jpa,ejb-3.1,Jpa,Ejb 3.1,我面临JPA EntityManager finder方法的问题。JPA实体使用的继承结构如下: //Need to persist this table to database @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Table(name="Table1") public class BaseE
//Need to persist this table to database
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="Table1")
public class BaseEntity implements Serializable {
@Id
@Column(name="PRIMARY_ID")
private long id;
private String field1;
.......
}
//This table will NOT persist and has parameters only for Sub classs
@MappedSuperclass
public abstract class MappedSuperClassEntity extends BaseEntity {
private String field2;
private String field3;
........
}
//This sub class is persisted and inherits fields form above class including Primary Key using TABLE_PER_CLASS strategy defined in BaseEntity
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="SubTable1")
public class Sub1 extends MappedSuperClassEntity {
private String field4;
private String field5;
...............
}
//This sub class is persisted and inherits fields form above class including Primary Key using TABLE_PER_CLASS strategy defined in BaseEntity
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="SubTable2")
public class Sub2 extends MappedSuperClassEntity {
private String field4;
private String field5;
..............
}
如您所见,Sub1和Sub2是持久化的实体,它们都扩展了用“@MappedSuperClass”注释的mappedsuperclasty。该类进一步继承了BaseEntity,该BaseEntity定义了表每类继承策略
我启用了hibernate stat收集器,发现hibernate正在使用父类的键存储子类对象。因此,在上述情况下,它将Sub1 finder的数据存储在缓存中,如下所示:
14:17:03941调试[org.hibernate.cache.TransactionalCache]缓存查找:com.abc.BaseEntity#10
14:17:03943调试[org.hibernate.cache.TransactionalCache]缓存未命中
14:17:03948调试[org.hibernate.cache.TransactionalCache]缓存:com.abc.BaseEntity#10
下次如果我为相同id(10)查找Sub2,hibernate会认为它在缓存中,因为它使用父类作为键,并返回Sub1对象,如下所示:
//Need to persist this table to database
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="Table1")
public class BaseEntity implements Serializable {
@Id
@Column(name="PRIMARY_ID")
private long id;
private String field1;
.......
}
//This table will NOT persist and has parameters only for Sub classs
@MappedSuperclass
public abstract class MappedSuperClassEntity extends BaseEntity {
private String field2;
private String field3;
........
}
//This sub class is persisted and inherits fields form above class including Primary Key using TABLE_PER_CLASS strategy defined in BaseEntity
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="SubTable1")
public class Sub1 extends MappedSuperClassEntity {
private String field4;
private String field5;
...............
}
//This sub class is persisted and inherits fields form above class including Primary Key using TABLE_PER_CLASS strategy defined in BaseEntity
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="SubTable2")
public class Sub2 extends MappedSuperClassEntity {
private String field4;
private String field5;
..............
}
14:27:54574调试[org.hibernate.cache.TransactionalCache]缓存查找:com.abc.BaseEntity#10
14:27:54575调试[org.hibernate.cache.TransactionalCache]缓存命中
因此,当您运行Sub1和Sub2的查找程序时,就会发生这种情况:
entityManager.find(Sub1.class, id); //returns Sub1 object
entityManager.find(Sub2.class, id); //returns Sub1 object (PROBLEM HERE).
请帮助我解决这个问题(我不想清除这些调用之间的缓存)问题是,您使用的是一个基本实体,而这是没有意义的。当您从基本实体继承时,而不仅仅是从映射的超类继承时,您不仅仅是在继承字段和方法。你正在建立一种关系 下面是一个有意义的例子:Car和Bike都继承了一个基本实体Vehicle。在这种情况下,汽车实体就是汽车实体。自行车实体是车辆实体 如果一辆车的ID为42,那么一辆自行车可能而不是也有ID 42,因为你会有两辆车具有相同的ID。想象一个司机实体与一辆车有很多联系(即司机驾驶一辆车)。如果我将ID 42存储在驾驶员表的vehicle_ID列中,则此ID 42必须唯一标识车辆。它可以是一辆汽车,也可以是一辆自行车,hibernate可以同时查看两张表,但不能同时查看两张表
你违反了这个继承概念。BaseEntity不应使用实体进行注释。它应该只是一个MappedSuperclass,它只允许继承字段和方法,但不建立这种语义关联。是一个关联。发布您的映射。我已经给出了完整的结构,请看一看并提出建议感谢您的回复,并理解您试图在这里解释的内容。在我的例子中,当对该对象调用persist时,我也需要持久化BaseEntity类。如果我将它标记为MappedSuperClass,我如何实现这一点。如果不能做到这一点,这是否意味着要让它正常工作,我需要确保始终以完整的继承结构唯一地保留记录?