2015-06-22 10 views
11

Ho due tabelle con riferimenti di chiave esterna:righe mancanti con valore vuoto nella query hibernate

Comm TABLE: 

+----+------------+ 
| ID | NAME | 
+----+------------+ 
| 1 | comm name1 | 
| 2 | comm name2 | 
| 3 | comm name3 | 
+----+------------+ 

LOCATION TABLE: - COMM_ID FK to Comm --> id 

+---------+------+-----+ 
| COMM_ID | FORM | TO | 
+---------+------+-----+ 
|  1 | 720 | 721 | 
|  1 | 725 |  | 
|  1 |  | 766 | 
|  1 |  |  | 
|  2 | 766 | 225 | 
|  3 | 766 | 222 | 
+---------+------+-----+ 

Il problema è Hibernate ritorna il mio oggetto comm mancante location in SET<location> Tutte le righe in cui non v'è alcun FROMeTO (come l'ultima riga con COMM_ID = 1 nella tabella LOCATION) mancano.

In caso contrario (se solo uno di FROM o TO) la riga viene restituita ... perché?

Comm oggetti:

@ElementCollection 
@CollectionTable(name="LOCATION",[email protected](name="COMM_ID")) 
public Set<LOCATION> getLocations(){ 
    return locations; 
} 
public void setLocations(Set<LOCATION> locations){ 
    this.locations=locations; 
} 

Location classe:

@Embeddable 
class Location implements java.io.Serializable { 

    private BigDecimal fromLocationId; 
    private BigDecimal toLocationId; 

    public Location() { 
    } 

    public Location(BigDecimal fromLocationId, BigDecimal toLocationId) { 
     this.fromLocationId = fromLocationId; 
     this.toLocationId = toLocationId; 
    } 

    @Column(name="FROM", nullable=true, precision=22, scale=0) 
    public BigDecimal getFromLocationId() { 
     return this.fromLocationId; 
    } 

    public void setFromLocationId(BigDecimal fromLocationId) { 
     this.fromLocationId = fromLocationId; 
    } 

    @Column(name="TO", nullable=true, precision=22, scale=0) 
    public BigDecimal getToLocationId() { 
     return this.toLocationId; 
    } 

    public void setToLocationId(BigDecimal toLocationId) { 
     this.toLocationId = toLocationId; 
    } 

    @Override 
    public int hashCode() { 
     return com.google.common.base.Objects.hashCode(fromLocationId, toLocationId); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null || getClass() != obj.getClass()) { 
      return false; 
     } 
     final LOCATION other = (LOCATION) obj; 
     return com.google.common.base.Objects.equal(this.fromLocationId, other.fromLocationId) && com.google.common.base.Objects.equal(this.toLocationId, other.toLocationId); 
    } 
} 

Sto usando Hibernate - 4.3.6

LOG:

org.hibernate.SQL - 
    select 
     locations0_.COMM_ID as COMM_ID1_2_0_, 
     locations0_.FROM as FROM2_8_0_, 
     locations0_.TO as TO4_8_0_ 
    from 
     LOCATION locations0_ 
    where 
     locations0_.COMM_ID=1 

Ho controllato nel mio DB e restituisce il risultato corretto.

+0

Mi manca qualcosa? i tuoi dati mostrano da e per essere stringhe, ma la tua mappatura dice che dovrebbero essere numeri ???? –

+0

scusate l'ho aggiustato .. – user986474

+0

Si prega di postare l'intera classe 'LOCATION'. Dato che stai usando 'Set', è obbligatorio sovrascrivere correttamente il metodo' equals' e 'hashCode'. – Tom

risposta

2

In realtà, non c'è niente di sbagliato nell'output. Penso che hai appena confuso tra embeddable e entity. perché, per quanto ne so. Si utilizza solo la classe embeddable solo per rendere molto più semplice lo sviluppo di un'entità se vi sono molte entità che utilizzano gli stessi campi.

E da quello che vedo, i metodi hashcode e equals trattano tutti quei sei record come un altro record. Quindi, penso che quello che vuoi sia rendere la classe Location in qualcosa di simile.

@Entity 
class Location implements java.io.Serializable { 

private Long commId; 
private BigDecimal fromLocationId; 
private BigDecimal toLocationId; 

// all the setter getter here 

@Override 
public int hashCode() { 
    return com.google.common.base.Objects.hashCode(commId); 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) { 
     return true; 
    } 
    if (obj == null || getClass() != obj.getClass()) { 
     return false; 
    } 
    final LOCATION other = (LOCATION) obj; 
    return com.google.common.base.Objects.equal(this.commId, other.commId); 
} 
} 

o, naturalmente è possibile effettuare il metodo get per restituire un List e poi rimuovere una riga se la riga manca from o to valore.

2

I dati di un oggetto incorporabile sono contenuti in diverse colonne nella tabella dei genitori. Poiché non esiste un singolo valore di campo, non è possibile sapere se il riferimento di un genitore all'inserimento è nullo. Si potrebbe supporre che, se ogni valore di campo di un incorporabile è nullo, il riferimento dovrebbe essere nullo, ma non c'è modo di rappresentare un elemento integrabile con tutti i valori nulli. JPA non consente l'inclusione di oggetti incorporabili, ma alcuni provider JPA potrebbero supportarli.

Ibernazione: quando si carica un'entità, i riferimenti incorporati vengono impostati su null se tutte le colonne nell'inediabile sono nulle.

per ulteriori informazioni click here

così quando u salvataggio dei valori embeddable nullable poi letargo consentono di salvare, ma al momento di andare a prendere hibernate scartare quelle file che sono annullabili.