2015-03-23 4 views
1

Я пытаюсь использовать JPA в первый раз в проекте. Большинство моих сущностей работают нормально, но у меня возникают проблемы с тем, что является частью стратегии наследования наследования. Сущности также сериализуются Jackson, поэтому у них также есть аннотации Json.JPA Сущность игнорируется

Родительский класс "Пользователь": (Edit: добавлено поле "Тип")

@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(); 
} 

Ребенок "Сотрудник"

@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(); 
    } 
} 

И ребенок "Клиент": (Edit : удалены @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; 
    } 

} 

persistence.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.all найти всех сотрудников в базе данных.

Однако, если я пытаюсь найти всех клиентов, я получаю ошибки. Если я пытаюсь запустить именованный запрос Customer.all я получаю:

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

Если я пытаюсь использовать находку EntityManager (в) метод, чтобы найти конкретный клиент, я получаю:

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. Я проверил таблицу пользователя, и столбец «type» там с правильными номерами, и @DescriminatorValue установлен правильно. Это похоже на то, что аннотации игнорируются?

Проделали много чистых перестроек и перераспределителей. Любая помощь будет очень высоко ценится!

+0

Я вижу, что вы определили имя пользователя @Id private String; в компоненте Customer, но не в Employee. Я думаю, вы должны держать его в соответствии. (если я правильно помню, он должен быть определен только в родительском) –

+0

любые изменения, которые вы поместили в класс клиента в неправильном пакете? Или в тестовой ветке кода? Нет ошибок jpa в журналах при запуске? – Zielu

+0

Спасибо за быстрые ответы! Поле @Id в клиенте - это то, что я добавил в качестве эксперимента после начала проблемы, я удалил его снова и не изменил. – Rag

ответ

1

В конце концов я нашел это. https://bugs.eclipse.org/bugs/show_bug.cgi?id=429992 Оказывается, EclipseLink молча игнорирует объекты с лямбда-выражениями! Очень раздражает, чтобы это не было, по крайней мере, упомянуто в журналах!

Спасибо всем, кто нашел время!

Смежные вопросы