对ORM / JPA使用单表策略时,如何使用从JPQL的父实体继承的属性列

如何解决对ORM / JPA使用单表策略时,如何使用从JPQL的父实体继承的属性列

我有3个班级:User,Admin,normalUser

Admin和normalUser扩展了用户类,当映射到derby db表时,我使用单表策略进行继承,并且发现如果我在normalUser类中使用继承的属性编写命名查询,则会出现错误。可以从下面的代码中引用更多信息:

package entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.discriminatorColumn;
import javax.persistence.discriminatorType;
import javax.persistence.discriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;


@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@discriminatorColumn(name="user_type",discriminatorType = discriminatorType.STRING)
@discriminatorValue("Null")
@Table(name="ALLUSER")
@NamedQueries({
    @NamedQuery(name = "User.findAll",query = "SELECT u FROM User u"),@NamedQuery(name = "User.findByAccount",query = "SELECT u FROM User u WHERE u.account = :account")
})
public class User implements Serializable{
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String account;
    private String password;
    private String userType;
    
    public User() {
        super();
    }
    public User(String account,String password) {
        super();
        this.account = account;
        this.password = password;
    }
    
    @Id
    @Column(name = "account")
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    
    @Column(name = "password")
    public String getpassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Column(name = "user_type",insertable = false,updatable = false,nullable = false)
    public String getUserType() {
        return userType;
    }
    public void setUserType(String userType) {
        this.userType = userType;
    }
    
    @Override
    public String toString() {
        return account;
    }
}

package entity;


import java.io.Serializable;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.discriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OnetoMany;



@Entity
@discriminatorValue("normal")
@NamedQueries({
    @NamedQuery(name = "normalUser.findAll",query = "SELECT u FROM normalUser u")
})
public class normalUser extends User implements Serializable{
    
    /**
     * 
     */
    //private String account;
    private static final long serialVersionUID = 1L;
    private LinkedHashSet<Customer> customers;
    
    public normalUser() {
        super();
    }
    

    @OnetoMany(fetch=FetchType.EAGER,mappedBy="user",cascade = {CascadeType.PERSIST,CascadeType.MERGE}) //delete user will delete all customer
    public LinkedHashSet<Customer> getCustomers() {
        return customers;
    }

    public void setCustomers(LinkedHashSet<Customer> customers) {
        this.customers = customers;
    }
    
//  @Column(name = "account")
//  //have to override in order to get account to use
//  public String getAccount() {
//      return account;
//  }
//  
//  public void setAccount(String account) {
//      this.account = account;
//  }
}

如果我使用普通用户的继承属性编写命名查询

package entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OnetoMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Entity
@Table(name="CUSTOMER")
@NamedQueries({
    @NamedQuery(name = "Customer.findAll",query = "SELECT c FROM Customer c order by c.customerID desc"),@NamedQuery(name = "Customer.findByUser",query = "SELECT c FROM Customer c WHERE c.normalUser.account = :account")
})
public class Customer implements Serializable {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int customerID;
    private Industry customerIndustryType;
    private String customerName;
    private Address customerAddress;
    private String customerNationality;
    private Date customerAddedDate;
    private Double customerdiscountRate;
    private String customerScale;
    private List<Contact> customerContacts;
    private normalUser normalUser;
    //getter and setter omited .....
}

运行它时将引发错误,并且显然与访问父属性的此查询有关:

screenshot of error information

实际上,我也尝试使用标准API,但它也失败了:

//          customers = entityManager.createNamedQuery("Customers.findByAccount",Customer.class).setParameter("account",role).getResultList();
//          CriteriaBuilder builder = entityManager.getCriteriaBuilder();
//          CriteriaQuery<Customer> criteriaQuery = builder.createquery(Customer.class);
//          Root<Customer> c = criteriaQuery.from(Customer.class);
//          criteriaQuery.select(c).where(builder.equal(c.get("normalUser").get("account"),role)); //(p.get("price"),budget));//danger4
//          Query query = entityManager.createquery(criteriaQuery);     
//          //List<Property> properties = query.getResultList();
//          customers =  query.getResultList();

那么如何使用父对象的属性?它不应该是这样。如果我扩展类,我将拥有所有继承的属性,不是吗?

-------------------------------------------------更新- ----------------------------

继承的属性可以在JPQL中使用。只是我们必须始终记得在对它进行注释时检查getter名称,这是JPQL中解决的问题。 希望将来的访客记得注意细节。 大声笑,最大的错误来自最简单的错误。 好消息是由于这个错误,我必须通过user.getCustomers()访问客户,因为它是双向的。结果,我学到了很多保持双向关系的方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?