2012-08-27 56 views
10

Estoy intentando crear una clase base para un conjunto de entidades para reducir el esfuerzo de codificación y la duplicación. Mi opinión es que la clase base tiene los campos comunes de metadatos, y las clases secundarias tratan sus atributos únicos.@Entity no reconoce @Id en @MappedSuperclass

Mi clase base:

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

La primera entidad:

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

He pruebas escritas que utilizan este código para hacer funciones CRUD en la entidad de etiqueta, y todos ellos están trabajando muy bien.

Mi pregunta es - ¿por qué Eclipse (Indigo) insistir en que Tag tiene un error:

The entity has no primary key attribute defined

que he cambiado a una advertencia por ahora así que mi código se compilará, pero estoy Curioso por qué Eclipse no es feliz, y si he entendido mal algo.

¿Este código JPA 2.0 es válido? Hibernate 4.1.5 es mi proveedor de JPA.

+0

Esta advertencia/error es incorrecto, solo puede deshabilitarla en las preferencias – Kemoda

Respuesta

8

Al usar acceso mixto, debe especificar el tipo de acceso. Consulte Eclipse Dali bug 323527 para obtener un mejor error de validación cuando se anotan los campos y las propiedades.

Opción 1: Anotar el método getVersion() en su lugar, solo las propiedades están anotadas.
Opción 2: Especificar tipo de acceso mixto de la siguiente manera:

@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; 
    } 
} 
+0

¡Bingo!Resultó que había utilizado el acceso de campo en el campo de versión, aunque había utilizado el acceso a la propiedad en el resto de los campos. Tan pronto como creé los accessors para mi campo de versión y moví mi anotación @Version al getter, ¡el error desapareció! – Jay

2

Estoy bastante seguro de que son asignaciones válidas.

La especificación JPA 2.0 proporciona este ejemplo cuando se habla de MappedSuperClasses (sección 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) { ... } 
} 
7

Si FinanceEntityBean se define en un proyecto Eclipse diferente de Tag, que puede estar sufriendo desde el fallo de Dali "No primary key attribute in other plug-in project" .

La solución alternativa es listar FinanceEntityBean en el archivo persistence.xml asociado con Tag.

+1

Mi error es diferente, y yo (gracias a Dali) ya tengo FinanceEntityBean en mi persistence.xml, por lo que la solución no funcionó en mi caso , pero aprecio la referencia al error Dali. – Jay

0

Yo tenía el mismo problema, pero por una razón diferente, pero no me daba cuenta. En una investigación posterior descubrí que en mi caso tenía MappedSuperclass en un jar diferente. De acuerdo con el usuario Gas https://stackoverflow.com/users/3701228/gas:

"Según las especificaciones de JPA, si tiene clases jpa en un contenedor separado, debe agregarlo a persistence.xml (no sé, si Hibernate lo requiere, pero puede proporcionarlo). intente). Intente agregar la siguiente entrada a su persistence.xml entity.jar "

Él hace referencia a what is the right path to refer a jar file in jpa persistence.xml in a web app? como una descripción de cómo hacer esto.