【发布时间】:2019-11-25 23:43:49
【问题描述】:
我能够像本教程一样使用 SINGLE_TABLE 继承策略将我的模型与实体映射 https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance#Avoiding_Inheritance
Base 类初始化良好,但是当我尝试访问最派生的部分属性时,我得到空值。
由于我是 EcliseLink / Hibernate 的初学者,我认为问题在于映射...
基类
@Entity
@Table(name="event")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "EVENT_TYPE")
public abstract class Events implements Serializable {
public Events(){
}
public Events(java.sql.Date date, int totalPlaces, int availablePlaces, String shortDescription,
String longDescription) {
Date = date;
TotalPlaces = totalPlaces;
AvailablePlaces = availablePlaces;
ShortDescription = shortDescription;
LongDescription = longDescription;
this.location = location;
this.picture = picture;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected int Id;
@Basic(optional=false)
protected Date Date;
@Basic(optional=false)
protected String Company;
@Basic(optional=false)
protected int TotalPlaces;
@Basic(optional=false)
protected int AvailablePlaces;
@Column(nullable = true, name="ShortDescription")
protected String ShortDescription;
@Column(nullable = true, name="LongDescription")
protected String LongDescription;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(name="Id")
protected Location location;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(name="Id")
protected Pictures picture;
abstract public String getCompany() {
return "Hochschule";
}
public void setCompany(String company) {
//
}
abstract public Double getPrice();
public void setPrice(Double price) {
//
}
abstract public void identify();
//gtrs strs
派生部分
@Entity
@DiscriminatorValue(value="EXCURSION")
public class Excursion extends Events {
public Excursion(){
}
public Excursion(java.sql.Date date, Double price, int totalPlaces, int availablePlaces, String shortDescription, String longDescription) {
super(date, totalPlaces, availablePlaces, shortDescription, longDescription);
this.Price = price;
}
@Basic(optional=false)
private Double Price;
@Override
public Double getPrice() {
System.out.println("Derived Part getPrice called ");
return Price;
}
@Override
public String getCompany(){
return "Hochschule Ulm";
}
@Override
public void setPrice(Double price) {
Price = price;
}
@Override
public void identify(){
System.out.println("This is Excursion");
}
}
主要
List<Events> ls = em.createNamedQuery("Events.findAllEvents").getResultList();
for(Events e : ls){
e.identify();
System.out.println(e.getId()+" "+e.getPrice());
// getPrice() returns null for every record
}
}
【问题讨论】:
-
您是如何创建和持久化 Excursions 的?对于有价格的行,数据库中的行是什么样的?查询是返回一个价格为空的 Excursion 实例还是它们是其他一些 Event 子类实例?
-
@Chris 查询实际上返回子类的实例,我使用 e.indentify() 来验证。子类的 Db 行相同。 price, company 可以为空,并且它们在 DB 中有默认值。如何创建 Excursion 的示例:
Excursion e1 = new Excursion(date, price, totalPlaces, availablePlaces, shortDescription, longDescription)然后我使用 entityManager 来持久化它。 -
发出了什么 SQL 语句?对于查询和插入?使用默认值可能会对缓存产生奇怪的行为。如果您在调用 persist 时实例的值为 null,那么您将获得该值,直到您使用 em.refresh 从数据库刷新它或重新启动应用程序。
-
@Chris 我根本没有使用 SQL 语句进行插入。我使用 MySQL 工作台进行测试,实体正确持久化,默认值由 DB 分配。顺便说一句,我已经解决了这个问题,谢谢你的提示。
-
JPA 规范、所有 EclipseLink 单元测试以及我自己的测试表明,如果您查询根类,它会很好地构建并返回子类实例。如果您可以发出多个查询而不是能够在继承层次结构中查询父级,那么就这样吧,但是您的答案对我来说似乎不是一个长期的解决方案,而且您似乎使用的模型不'没有正确设置继承。对于发出的 SQL,您需要适当地设置 EclipseLink 日志级别以记录它正在使用的内容:wiki.eclipse.org/EclipseLink/Examples/JPA/Logging
标签: java orm polymorphism eclipselink