2013-01-20 7 views
5

Ho bisogno di aiuto per il prossimo problema che sembra abbastanza simile a questo one. Tuttavia, la soluzione suggerita non funziona nel mio caso. Ho la classe RoadDistance che è contrassegnata come @Embbedable e la classe RoadMetricLoader, che è anche @Embbedable e contiene due attributi di tipo RoadDistante. Esiste anche la classe RoadConnection, che è un'entità e include un attributo del tipo RoadmetricLoader. Io non sono un successo in ignorando gli attributi (@AttributeOverride) di RoadMetricLoader per la RoadDistance di classe (non ottengo i campi ROAD_ESTIMATED_DISTANCE_VALUE, ROAD_ESTIMATED_DISTANCE_UNIT_ID, ROAD_REAL_DISTANCE_VALUE e ROAD_REAL_DISTANCE_UNIT_ID nella ROAD_CONNECTION tabella)JPA 2.0: @AttributeOverrides e attributi ereditati non vanno d'accordo tra loro

Il database è MySQL 5.2.21 e la le librerie utilizzate per JPA 2.0 sono quelle di EclipseLink 2.4.1

Ho provato diverse opzioni ma nessuna funziona. Ho mostrato tutte le opzioni nei blocchi commentati nel codice che puoi vedere qui sotto. Quando un'opzione non commentata mantiene gli altri commentati. Questi sono il risultato che ottengo in ogni caso:

OPZIONE 1: Esso non restituisce alcun errore, ma nel ROAD_CONNECTION tavolo ottengo solo due fieds: VALUE e UNIT_ID.

OPZIONE 2: lo stesso risultato che OPZIONE 1.

OPZIONE 3: Questa era la mia prima scommessa (vedi official documentation example 2, e il collegamento già sopra indicato), ma ottengo l'errore successivo

Local Exception Stack: 
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException 
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: [email protected] 
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.EntityManagerSetupException 
Exception Description: Predeployment of PersistenceUnit [jamUnit] failed. 
Internal Exception: Exception [EclipseLink-7309] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: The attribute named [estimatedRoadDistance.unit] from the embeddable class [class net.question.RoadMetricLoader] is not a valid mapping to use with an attribute override for the attribute [metricLoader] on class [class net.question.RoadConnection]. 
    at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:118) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    (...) 

OPZIONE 4: identica all'opzione 1 e 2.

OPZIONE 5:

Local Exception Stack: 
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException 
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: [email protected] 
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.EntityManagerSetupException 
Exception Description: Predeployment of PersistenceUnit [jamUnit] failed. 
Internal Exception: Exception [EclipseLink-7309] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: The attribute named [unit] from the embeddable class [class net.question.RoadDistance] is not a valid mapping to use with an attribute override for the attribute [estimatedRoadDistance] on class [class net.question.RoadMetricLoader]. 
    at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:118) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    (...) 

@Entity 
@Table(name="UNIT") 
public class Unit { 

    private Long id; 
    private String name; 
    private String measureSystemCode; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO, generator="UNIT_SEQ_GENERATOR") 
    @SequenceGenerator(name="UNIT_SEQ_GENERATOR", sequenceName="UNIT_SEQ") 
    @Column(name = "ID") 
    public Long getId() { 
     return id; 
    } 

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

    @Column(name = "NAME", nullable = false) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @Column(name = "MEASURE_SYSTEM_CODE", nullable = false) 
    public String getMeasureSystemCode() { 
     return measureSystemCode; 
    } 

    public void setMeasureSystemCode(String measureSystemCode) { 
     this.measureSystemCode = measureSystemCode; 
    } 

} 

@MappedSuperclass 
public abstract class Metric<V extends Comparable<V>> { 

    private V value; 
    private Unit unit; 

    @Column(name = "VALUE", nullable = false) 
    public V getValue() { 
     return value; 
    } 

    public void setValue(V value) { 
     this.value = value; 
    } 

    @ManyToOne 
    @JoinColumn(name = "UNIT_ID", nullable = false) 
    public Unit getUnit() { 
     return unit; 
    } 

    public void setUnit(Unit unit) { 
     this.unit = unit; 
    } 

} 

@MappedSuperclass 
public abstract class ScalarPhysicalMetric<M extends Number & Comparable<M>> 
extends Metric<M> { 

} 

@Embeddable 
public final class RoadDistance extends ScalarPhysicalMetric<Double> { 

} 

/* 
// -##----------- OPTION 4 ----------> 
@AttributeOverrides({ 
    @AttributeOverride(name = "estimatedRoadDistance.value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")), 
    @AttributeOverride(name = "estimatedRoadDistance.unit", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")), 
    @AttributeOverride(name = "realRoadDistance.value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")), 
    @AttributeOverride(name = "realRoadDistance.unit", column = @Column(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
}) 
// <---------- OPTION 4 -----------##- 
*/ 
@Embeddable 
public final class RoadMetricLoader { 

    private RoadDistance estimatedRoadDistance; 
    private RoadDistance realRoadDistance; 

    @Embedded 
    /* 
    // -##----------- OPTION 5 ----------> 
    @AttributeOverrides({ 
     @AttributeOverride(name = "value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")), 
     @AttributeOverride(name = "unit", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")) 
    }) 
    // <---------- OPTION 5 -----------##- 
    */ 
    public RoadDistance getEstimatedRoadDistance() { 
     return estimatedRoadDistance; 
    } 

    public void setEstimatedRoadDistance(RoadDistance estimatedRoadDistance) { 
     this.estimatedRoadDistance = estimatedRoadDistance; 
    } 

    @Embedded 
    /* 
    // -##----------- OPTION 5 ----------> 
    @AttributeOverrides({ 
     @AttributeOverride(name = "value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")), 
     @AttributeOverride(name = "unit", column = @Column(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
    }) 
    // <---------- OPTION 5 -----------##- 
    */ 
    public RoadDistance getRealRoadDistance() { 
     return realRoadDistance; 
    } 

    public void setRealRoadDistance(RoadDistance realRoadDistance) { 
     this.realRoadDistance = realRoadDistance; 
    } 

} 

// -##----------- OPTION 1 ----------> 
/* 
@AttributeOverrides({ 
    @AttributeOverride(name = "estimatedRoadDistance.value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")), 
    @AttributeOverride(name = "estimatedRoadDistance.unit", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")), 
    @AttributeOverride(name = "realRoadDistance.value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")), 
    @AttributeOverride(name = "realRoadDistance.unit", column = @Column(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
}) 
// <---------- OPTION 1 -----------##- 
*/ 
/* 
// -##----------- OPTION 2 ----------> 
@AttributeOverrides({ 
    @AttributeOverride(name = "metricLoader.estimatedRoadDistance.value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")), 
    @AttributeOverride(name = "metricLoader.estimatedRoadDistance.unit", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")), 
    @AttributeOverride(name = "metricLoader.realRoadDistance.value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")), 
    @AttributeOverride(name = "metricLoader.realRoadDistance.unit", column = @Column(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
}) 
// <---------- OPTION 2 -----------##- 
*/ 
@Entity 
@Table(name="ROAD_CONNECTION") 
public class RoadConnection { 

    private Long id; 
    private String pointA; 
    private String pointB; 
    private RoadMetricLoader metricLoader; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO, generator="ROAD_CONNECTION_SEQ_GENERATOR") 
    @SequenceGenerator(name="ROAD_CONNECTION_SEQ_GENERATOR", sequenceName="ROAD_CONNECTION_SEQ") 
    @Column(name = "ID") 
    public Long getId() { 
     return id; 
    } 

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

    @Column(name = "POINT_A", nullable = false) 
    public String getPointA() { 
     return pointA; 
    } 

    public void setPointA(String pointA) { 
     this.pointA = pointA; 
    } 

    @Column(name = "POINT_B", nullable = false) 
    public String getPointB() { 
     return pointB; 
    } 

    public void setPointB(String pointB) { 
     this.pointB = pointB; 
    } 

    /* 
    // -##----------- OPTION 3 ----------> 
    @AttributeOverrides({ 
     @AttributeOverride(name = "estimatedRoadDistance.value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")), 
     @AttributeOverride(name = "estimatedRoadDistance.unit", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")), 
     @AttributeOverride(name = "realRoadDistance.value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")), 
     @AttributeOverride(name = "realRoadDistance.unit", column = @Column(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
    }) 
    // <---------- OPTION 3 -----------##- 
    */ 
    @Embedded 
    public RoadMetricLoader getMetricLoader() { 
     return metricLoader; 
    } 

    public void setMetricLoader(RoadMetricLoader metricLoader) { 
     this.metricLoader = metricLoader; 
    } 

} 

risposta

4

AttributeOverride sono per mappature di base. Ciò di cui hai bisogno è AssociationOverride: http://docs.oracle.com/javaee/6/api/javax/persistence/AssociationOverride.html

+0

Grazie mille per il vostro replay. Ho provato anche quello che dici come alternativa all'OPZIONE 3 (Nella stessa posizione su getMetricLoader) -Infine, ho provato più opzioni di quelle che ho indicato-. Istanza di dichiarare tutti gli attributi come AttributeOverride I taggati "EstimateRoadDistance.unit" e "realRoadDistance.unit" come AssociationOverride. Nel database ho ottenuto la tabella road_connection con i campi: ID, POINT_A, POINT_B, ROAD_ESTIMATED_DISTANCE_VALUE, ROAD_REAL_DISTANCE_UNIT_ID, UNIT_ID. Non so perché ci vogliono alcuni campi correttamente e altri sbagliano. – GYLZ

+0

In google, se si cerca "non è una mappatura valida da utilizzare con una sovrascrittura dell'attributo per l'attributo" (virgolette incluse), vedere gli errori generati per OPZIONI 3 e 5 solo alcune voci e non troppo utili. – GYLZ

+0

Le sostituzioni si trovano normalmente sulla mappatura nell'entità, quindi l'opzione 3 è l'unica da utilizzare, con AssotiationOverride per i mapping delle relazioni. Detto questo, non sono sicuro che sia valido per un embeddable per estendere una classe di riferimento mappates, poiché sono pensati per le entità. Se è qualcosa richiesto dalle specifiche, potresti dover compilare un bug con Eclipselink. – Chris

1

Come consigliato da @Chris, deve essere utilizzato AssociatedOverride.Se si cambia RoadMetricLoader come segue:

public final class RoadMetricLoader { 

    private RoadDistance estimatedRoadDistance; 
    private RoadDistance realRoadDistance; 

    @Embedded 
    @AttributeOverrides({ 
     @AttributeOverride(name = "value", column = @Column(name = "ROAD_ESTIMATED_DISTANCE_VALUE")) 
    }) 
    @AssociationOverrides({ 
     @AssociationOverride(name = "unit", joinColumns = @JoinColumn(name = "ROAD_ESTIMATED_DISTANCE_UNIT_ID")) 
    }) 
    public RoadDistance getEstimatedRoadDistance() { 
     return estimatedRoadDistance; 
    } 

    public void setEstimatedRoadDistance(RoadDistance estimatedRoadDistance) { 
     this.estimatedRoadDistance = estimatedRoadDistance; 
    } 

    @Embedded 
    @AttributeOverrides({ 
     @AttributeOverride(name = "value", column = @Column(name = "ROAD_REAL_DISTANCE_VALUE")) 
    }) 
    @AssociationOverrides({ 
     @AssociationOverride(name = "unit", joinColumns = @JoinColumn(name = "ROAD_REAL_DISTANCE_UNIT_ID")) 
    }) 
    public RoadDistance getRealRoadDistance() { 
     return realRoadDistance; 
    } 

    public void setRealRoadDistance(RoadDistance realRoadDistance) { 
     this.realRoadDistance = realRoadDistance; 
    } 

ora la tabella viene creata correttamente nel DB:

enter image description here

In questo caso, è anche possibile sbarazzarsi di @AttributeOverrides e @AssociationOverrides in quanto vi è solo un elemento per ognuno.

Problemi correlati