【问题标题】:Null output for derived class attributes派生类属性的空输出
【发布时间】: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


【解决方案1】:

好的,我自己解决了这个问题。派生部分根本没有被初始化。当我从数据库中获取所有事件时,只有事件的基础部分被初始化。我发现这样做的方法是,分别获取所有子类,然后将它们存储在列表中

List<Excursion> le = em.createNamedQuery("Excursion.findAllExcursions").getResultList();
List<CompanyExcursion> lc = em.createNamedQuery("CompanyExcursion.findAllExcursions").getResultList();

List<Events> ls = new ArrayList<>();
ls.addAll(le);
ls.addAll(lc);

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多