@Entity не распознает @Id в @MappedSuperclass

Я пытаюсь создать базовый класс для набора сущностей для уменьшения усилий и дублирования кодирования. Я думал, что базовый класс имеет общие поля метаданных, а дочерние классы имеют свои уникальные атрибуты.

Мой базовый класс:

@MappedSuperclass
public abstract class FinanceEntityBean {
    protected Long id;

    @Version
    private long version;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(final Long id) {
        this.id = id;
    }
}

Первый объект:

@Entity
@Table(name = "tag")
public class Tag extends FinanceEntityBean {
}

Я написал тесты, используя этот код, чтобы выполнять функции CRUD в объекте Tag, и все они работают нормально.

Мой вопрос: почему Eclipse (Indigo) настаивает на том, что Tag имеет ошибку:

The entity has no primary key attribute defined

Я изменил это на предупреждение, так что мой код будет компилироваться, но мне любопытно, почему Eclipse не доволен, и если я что-то не понял.

Является ли это действующим кодом JPA 2.0? Hibernate 4.1.5 - мой поставщик JPA.

Ответ 1

При использовании смешанного доступа вы должны указать тип доступа. См. Eclipse Dali ошибка 323527 для получения лучшей ошибки проверки при аннотации обоих полей и свойств.

Вариант 1: аннотировать метод getVersion(), но только аннотации свойств.
Вариант 2: укажите тип смешанного доступа следующим образом:

@MappedSuperclass
@Access(AccessType.PROPERTY)
public abstract class FinanceEntityBean {
    protected Long id;

    @Version
    @Access(AccessType.FIELD)
    private long version;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(final Long id) {
        this.id = id;
    }
}

Ответ 3

Я уверен, что это допустимые сопоставления.

Спецификация JPA 2.0 предоставляет этот пример, когда речь идет о MappedSuperClasses (раздел 2.11.2):

@MappedSuperclass 
public class Employee {
    @Id protected Integer empId; 
    @Version protected Integer version; 
    @ManyToOne @JoinColumn(name="ADDR") protected Address address;
    public Integer getEmpId() { ... } 
    public void setEmpId(Integer id) { ... } 
    public Address getAddress() { ... } 
    public void setAddress(Address addr) { ... }
}

// Default table is FTEMPLOYEE table 
@Entity public class FTEmployee extends Employee {
    // Inherited empId field mapped to FTEMPLOYEE.EMPID 
    // Inherited version field mapped to FTEMPLOYEE.VERSION 
    // Inherited address field mapped to FTEMPLOYEE.ADDR fk
    // Defaults to FTEMPLOYEE.SALARY protected Integer salary;
    public FTEmployee() {}
    public Integer getSalary() { ... } 
    public void setSalary(Integer salary) { ... }
}

Ответ 4

У меня была та же проблема, но по другой причине, но я этого не осознавал. В дальнейших исследованиях я обнаружил, что в моем случае у меня был MappedSuperclass в другой банке. Согласно User Gas https://stackoverflow.com/users/3701228/gas:

"Согласно спецификации JPA, если у вас есть классы jpa в отдельной банке, вы должны добавить ее в файл persistence.xml(я не знаю, если Hibernate требует этого, но вы можете попробовать). Попробуйте добавить после входа в ваш persistence.xml entity.jar"

Он ссылается на что такое правильный путь для ссылки jar файла в jpa persistence.xml в веб-приложении? как описание того, как это сделать.