2012-07-07 7 views
5

Sto implementando un servizio Web RESTful utilizzando Jersey. Io uso la sospensione per comunicare con il database (mySQL). Le mie classi di risorse di sospensione comprende:Molti-a-uno con join Tabella in classi di risorse di sospensione per un JAX-RS utilizzando Jersey

@Entity 
public class Activity { 

    @Id 
    @GeneratedValue 
    private long id; 

@ManyToOne 
    @JoinTable(name="category_activity", 
    joinColumns={@JoinColumn(name="activities_id")}, 
    inverseJoinColumns={@JoinColumn(name="Category_id")}) 
    private Category category; 
} 

e la classe Categoria:

@Entity 
public class Category { 

    @Id 
    @GeneratedValue 
    private long id; 

    @OneToMany 
    @Fetch(FetchMode.JOIN) 
    @JoinTable(name = "category_activity", 
    joinColumns = { @JoinColumn(name = "Category_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "activities_id") }) 
    @JsonIgnore 
    private Collection<Activity> activities; 
} 

Ho usato questa query per recuperare i ativities:

session.createQuery("from Activity a join a.category cs where cs.id= :categoryId order by a.key").setLong("categoryId", categoryId).list(); 

Il risultato in formato JSON non è giusto come :

[[{"id":26,"key":"other","name":"Other","cost":100.0,"category":{"id":10,"name":"General","description":""}},{"id":10,"name":"General","description":""}]] 

Come vedi la categoria viene stampata 2 volte e abbiamo un extra [] attorno ad esso. Quando uso un altro meccanismo di One-a-molti relazione in classe Categoria come:

@OneToMany(targetEntity = Activity.class, mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
@JsonIgnore 
private Collection<Project> activities; 

E in Classe di attività:

@ManyToOne(optional = false) 
    private Category category; 

E questa query:

session.createQuery("from Activity as a where a.category.id= :categoryId order by a.key").setLong("categoryId", categoryId).list(); 

Tutto funziona bene. Ma devo usare la tabella di join perché non suppongo di cambiare il database.

Il risultato corretto dovrebbe essere simile:

[{"id":26,"key":"other","name":"Other","cost":100.0,"category":{"id":10,"name":"General","description":""}}] 

apprezzo per qualsiasi aiuto.

risposta

9

Definire la tabella di unione su più lati, ma non definirla nuovamente su un lato. Ciò crea due associazioni unidirezionali mappate con la stessa tabella anziché una associazione bidirezionale.

Un'associazione bidirezionale ha sempre un lato proprietario (in cui si specifica la colonna di join o join tabella da utilizzare, e un lato inversa che dice il cappello che è l'inverso dell'altro lato utilizzando l'attributo mappedBy:

public class Activity { 

    @ManyToOne // owner side: it doesn't have mappedBy, and can decide how the association is mapped: with a join table 
    @JoinTable(name="category_activity", 
       joinColumns={@JoinColumn(name="activities_id")}, 
       inverseJoinColumns={@JoinColumn(name="Category_id")}) 
    private Category category; 
} 

public class Category { 
    @OneToMany(mappedBy = "category") // inverse side: it has a mappedBy attribute, and can't decide how the association is mapped, since the other side already decided it. 
    @Fetch(FetchMode.JOIN) 
    @JsonIgnore 
    private Collection<Activity> activities; 
} 

EDIT:

Inoltre, la query dovrebbe selezionare solo l'attività, e non tutti i soggetti uniti da query, con l'aggiunta di una clausola select:

select a from Activity as a where a.category.id= :categoryId order by a.key 
+0

i Apprec iate per la risposta. La soluzione che hai citato ha avuto lo stesso problema. – Ali

+0

Vedere la mia risposta modificata –

+0

Ora funziona perfettamente. – Ali

Problemi correlati