java - JPA 实体被忽略

标签 java jpa

我第一次尝试在项目中使用 JPA。我的大多数实体都工作正常,但我在使用联合继承策略中的一个实体时遇到了麻烦。这些实体也由 Jackson 序列化,因此它们也有 Json 注释。

父“用户”类: (编辑:添加“类型”字段)

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonTypeName("user")
@JsonSubTypes({
        @JsonSubTypes.Type(name="customer", value=Customer.class),
        @JsonSubTypes.Type(name="employee", value=Employee.class)})
@Entity(name = "User")
@Table(name="user")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.INTEGER)
@NamedQuery(name="User.all",query = "select u from User u")
public abstract class User {

    @Id
    private String username;
    @Column(name = "type",nullable = false)
    private int type;

    public User(){

    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public abstract Set<Order> getOrders();
}

child “雇员”

@JsonTypeName("employee")
@Entity(name="Employee")
@Table(name="employee")
@PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
@DiscriminatorValue("1")
@NamedQuery(name = "Employee.all",query = "select e from Employee e")
public class Employee extends User implements Serializable{

    private String username;
    private String firstName;
    private String lastName;
    private String email;
    @Convert(converter = LocalDatePersistenceConverter.class)
    private LocalDate dateStarted;
    @Convert(converter = LocalDatePersistenceConverter.class)
    private LocalDate dateEnded;

    @OneToMany(mappedBy = "employee",targetEntity = Order.class,fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
    @JsonIgnore
    private Set<Order> orders = new HashSet<>();

    public Employee() {

    }

    @Override
    public Set<Order> getOrders() {
        return orders;
    }

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }

    public void addOrder(Order order){
        orders.add(order);
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getEmail() {
        return email;
    }

    public String getDateStarted() {
        if(dateStarted != null)
            return dateStarted.toString();
        else return null;
    }

    public void setDateStarted(LocalDate dateStarted) {
        this.dateStarted = dateStarted;
    }

    public String getDateEnded() {
        if(dateEnded != null)
            return dateEnded.toString();
        else return null;
    }

    public void setDateEnded(LocalDate dateEnded) {
        this.dateEnded = dateEnded;
    }

    @Override
    public String toString(){
        return getUsername();
    }
}

还有一个 child “顾客”: (编辑:删除@Id字段)

@JsonTypeName("customer")
@Entity(name="Customer")
@Table(name="customer")
@PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
@DiscriminatorValue("2")
@NamedQueries({
        @NamedQuery(name="Customer.all",query = "select c from Customer c")
})
public class Customer extends User implements Serializable{

    public enum VIP_TYPE {NORMAL,SILVER,GOLD,DIAMOND}

    @Transient
    private static final int SILVER_THRESHOLD = 1000;
    @Transient
    private static final int GOLD_THRESHOLD = 2000;
    @Transient
    private static final int DIAMOND_THRESHOLD = 3000;

    private String firstName;
    private String lastName;
    private String email;
    private String address;
    private String postcode;
    private String mobileNumber;
    private String homeNumber;
    @Convert(converter = VipTypeConverter.class)
    private VIP_TYPE vipGroup;
    private String discount;

    @OneToMany(mappedBy = "customer",targetEntity = Order.class,fetch=FetchType.EAGER,cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<Order> orders = new HashSet<>();

    public Customer() {
    }

    @Override
    public Set<Order> getOrders() {
        return orders;
    }

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }

    public void addOrder(final Order order){
        orders.add(order);
        updateVipGroup();
    }

    private void updateVipGroup() {
        int sum = orders.stream().map(Order::getPayment).distinct().mapToInt(p->p.getAmmount()).sum();
        if(sum > DIAMOND_THRESHOLD){
            vipGroup = VIP_TYPE.DIAMOND;
            return;
        }
        if(sum > GOLD_THRESHOLD){
            vipGroup = VIP_TYPE.GOLD;
            return;
        }
        if(sum > SILVER_THRESHOLD){
            vipGroup = VIP_TYPE.SILVER;
            return;
        }
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setDiscount(String discount) {
        this.discount = discount;
    }

    public void setVipGroup(VIP_TYPE vipGroup) {
        this.vipGroup = vipGroup;
    }

    public void setHomeNumber(String homeNumber) {
        this.homeNumber = homeNumber;
    }

    public void setMobileNumber(String mobileNumber) {
        this.mobileNumber = mobileNumber;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    public String getDiscount() {
        return discount;
    }

    public VIP_TYPE getVipGroup() {
        return vipGroup;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getEmail() {
        return email;
    }

    public String getAddress() {
        return address;
    }

    public String getPostcode() {
        return postcode;
    }

    public String getMobileNumber() {
        return mobileNumber;
    }

    public String getHomeNumber() {
        return homeNumber;
    }

}

持久性.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="local" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/cod</jta-data-source>
        <class>com.technicalpioneers.cod.user.Customer</class>
        <class>com.technicalpioneers.cod.user.Employee</class>
        <class>com.technicalpioneers.cod.user.User</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
    </persistence-unit>
</persistence>

与“employee”工作文件有关的所有内容,我可以使用命名查询Employee.all来查找数据库中的所有员工。

但是,如果我尝试检索任何客户,则会出现错误。如果我尝试运行命名查询 Customer.all 我得到:

java.lang.IllegalArgumentException: NamedQuery of name: Customer.all not found.

如果我尝试使用 EntityManager 的 find() 方法来查找特定客户,我会得到:

javax.servlet.ServletException: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [2] of type [class java.lang.Integer].
Descriptor: RelationalDescriptor(com.technicalpioneers.cod.user.User --> [DatabaseTable(user)])

我不明白为什么 JPA 找不到客户实体。我检查了用户表,“类型”列中的数字正确,并且 @DecriminatorValue 设置正确。这几乎就像注释被忽略了?

也完成了许多干净的重建和重新部署。任何帮助将非常感激!

最佳答案

我最终找到了这个。 https://bugs.eclipse.org/bugs/show_bug.cgi?id=429992 事实证明,EclipseLink 将默默地忽略带有 lambda 表达式的实体!非常烦人的是它至少没有在日志中提及!

感谢所有抽出时间的人!

关于java - JPA 实体被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29211736/

相关文章:

java - 使用类或不使用类

java - 我可以在调用 Axis 2 Java 中的 stub 之前设置 MessageContext 的属性吗

Java:当您只能访问接口(interface)时复制对象

jpa - 不使用 ORM 进行查询的 Spring Data API

java - JPA:仅使用几个属性进行获取

java - PhysicalNamingStrategy bean 仅通过配置文件实例化

java - 有没有一种简单的方法可以使用 java Graphics 2D 对象淡入字符串字符?

java - 选择第二列(FileReader)

hibernate - Kotlin Hibernate JPA Lazy提取无法通过 Controller 工作

java - 如何告诉 Hibernate 注解 @Column 区分大小写?