2015-10-16 18 views
5

Ho la seguente entità ho bisogno di persistere per un DB relazionale tramite Hibernate annotazioni:oggetti di valore mappatura da librerie di terze parti

@Entity 
@Table(name="fizzes") 
public class Fizz { 
    @Id @GeneratedValue 
    @Column(name="fizz_id") 
    private int id; 

    @Column(name="fizz_wooz") 
    private String wooz; 

    // ??? here I am unsure! 
    private Buzz buzz; 

    // Constructor, getters/setters down here, etc... 
} 

public class Buzz { 
    private int jupiter; 

    private String neptune; 

    // Constructor, getters/setters down here, etc... 
} 

Il problema con Buzz è:

  • faccio non desidera che sia la propria entità/tabella. Voglio che sia un "oggetto valore/tipo" che viene mappata sulla tabella fizzes (mediante l'aggiunta di colonne ad esso)
  • Buzz è da una libreria di terze parti e quindi non può modificare lo

Quindi il risultato finale, in forma di tabella, che io sto cercando è:

[fizzes] table 
============== 
fizz_id, PRIMARY KEY AUTO INCREMENT 
fizz_wooz, NVARCHAR(50) NOT NULL 
fizz_buzz_jupiter, INT NOT NULL 
fizz_buzz_neptune, NVARCHAR(100) NOT NULL 

Come posso ottenere Hibernate per fare questa mappatura di annotazione a base quando non riesco a modificare Buzz?

+0

@TobiasLiefke - sì, non ho codice sorgente e non voglio violare alcuna licenza per apportare modifiche alle classi. Per quanto riguarda il motivo per cui ho desiderato annotazioni sulla mappatura dei file, preferisco le annotazioni perché sono più pulite (IMHO). Grazie ancora per l'aiuto! – DirtyMikeAndTheBoys

risposta

7

Quello che stai cercando si chiama Embeddable.

@Entity 
public class Fizz { 
    ... 

    @Embedded 
    private Buzz buzz; 

} 

E si può definire un file mappatura solo per Buzz:

<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm  
         http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"> 
    <embeddable class="...Buzz"> 
     <attributes> 
      <basic name="jupiter"><column name="fizz_buzz_jupiter"/></basic> 
      <basic name="neptune"><column name="fizz_buzz_neptune"/></basic> 
     </attributes> 
    </embeddable> 
</entity-mappings> 

È possibile includere il file di mapping nel persistence.xml:

<persistence-unit> 
    <mapping-file>.../orm.xml</mapping-file> 
</persistence-unit> 

Se davvero si vuole utilizzare annotazioni per Buzz: non è possibile definire annotazioni per altre classi. Questo è il significato delle annotazioni: sono inline e appartengono alla loro classe. Altrimenti non ci sarebbe alcun beneficio rispetto alla mappatura dei file ...

Ma si potrebbe estendere Buzz e l'uso che uno con accesso proprietà:

@Entity 
public class Fizz { 
    ... 

    @Embedded 
    private BuzzExtension buzz; 

} 

@Embeddable 
@Access(AccessType.PROPERTY) 
public class BuzzExtension extends Buzz { 
    @Column(name="fizz_buzz_jupiter") 
    public int getJupiter() { 
     return super.getJupiter(); 
    } 

    @Column(name="fizz_buzz_neptune") 
    public String getNeptune() { 
     return super.getNeptune(); 
    } 

} 

Unico inconveniente: non è possibile utilizzare le istanze di Buzz in Fizz.

+0

Grazie mille @Tobias Liefke (+1 e controllo verde)! – DirtyMikeAndTheBoys

1

Credo che si desidera che i properites di Buzz oggetto di essere presenti nell'oggetto Fizz che significa che sia le proprietà di Buzz e Fizz dovrebbero essere presenti come colonne nella stessa tabella fizzes.

quindi bisogna estendere l'oggetto Fizz dove il Buzz saranno annotati come @MappedSuperClass

@Entity 
@Table(name="fizzes") 
public class Fizz extends Buzz { 
    // Fizz properties 
    // No need to add Buzz as a field 
} 

@MappedSuperclass 
public class Buzz { 
    // Buzz properties 
} 

Se non si aggiunge @MappedSuperclass annotazione, quindi non si può raggiungere questo obiettivo. Anche se Fizz viene esteso a Fizz, i campi di Buzz non verranno riconosciuti da Hibernate poiché Hibernate esegue solo la riflessione sui campi presenti nello Fizz ma non sui campi presenti nella classe estesa Buzz, a meno che non si specifica l'annotazione @MappedSuperclass. MappedSuperclass indicherà all'ibernazione di utilizzare anche la riflessione sui campi dell'oggetto Buzz.

+0

Grazie @ user1354678 (+1) - tuttavia, ** Non riesco a modificare la sorgente di 'Buzz' !!! ** In altre parole, non posso aggiungere idee' @ MappedSuperclass' ...? – DirtyMikeAndTheBoys

+0

@DirtyMikeAndTheBoys, ho aggiornato la mia risposta. Non ho provato senza l'annotazione '@ MappedSuperclass'. Immagino che il modo di lavorare in letargo sia quello che ho spiegato nell'ultimo. Forse proverai senza l'annotazione '@ MappedSuperclass'. –

+0

Grazie ancora @ user1354678, ma stai * veramente * dicendo che Hibernate non può creare classi OR/M di proprietà di terze parti? Ad esempio, se alcuni JAR di terze parti di Maven Central contengono alcune classi che desidero persistere come oggetti/tipi di valore, mi stai dicendo che non c'è modo di farlo senza modificare la loro origine per contenere '@ MappedSuperclass'?!?! Se è vero, allora sono solo completamente * sconvolto *! – DirtyMikeAndTheBoys

Problemi correlati