Hoe voeg je een-op-veel associatie in de slaapstand toe aan een ingesloten type?

Ik heb een entiteit die de laatste instantie van een component bevat:

@Entity
public class Customer {
  ...
  @Embedded
  public ServiceCall getLastServiceCall() {...}
  ...
}

@Embeddable
public class ServiceCall() {
  public Date getDate();
  public Status getStatus();
}

De ServiceCall is ingesloten om customer.getLastServiceCall (). GetDate() aan te roepen zonder dat er nog een andere tafel nodig is.

Ik wil die associatie een-op-veel maken en begin met het opslaan van alle ServiceCall s, terwijl ik er een vasthoud die in de klant is ingebed.

Hibernate's Documenten (v3.6, die ik gebruik):

U kunt ook associatieannotaties gebruiken in een insluitbaar object (bijv. @OneToOne, @ManyToOne, @OneToMany of @ManyToMany). Als u de koppelingskolommen wilt overschrijven, kunt u @AssociationOverride gebruiken.

en het lijkt erop dat ik alleen maar @OneToMany aan de associatie LastServiceCall moet toevoegen.

Zal dat voor mij werken? Zo nee, wat zijn mijn alternatieven? Zo ja, welke invloed heeft dit op de cache op het tweede niveau en is er een beperking voor het bijwerken van die ingesloten instantie (ik kan leven met onveranderlijke objecten)?

2
kun je een tabelstructuur posten die je probeert te modelleren.
toegevoegd de auteur ams, de bron
Klant: ID, versie, aanmaakdatum, enz. + ServiceCallDate, ServiceCallStatus. Ik wil een andere tafel hebben, ServiceCall: ID, datum, status, etc.
toegevoegd de auteur Asaf, de bron

2 antwoord

@Gesmeerde typen mogen geen eigen identiteit hebben in de database, dus ik denk niet dat u @OneToMany aan de klasse Customer op de ServiceCall kunt toevoegen.

  @OneToMany 
  @Embedded
  public ServiceCall getLastServiceCall() {...}

U kunt echter als volgt een koppeling toevoegen aan het call-element @Embeded Service.

@Entity 
pubic class HistoricalServiceCall extends ServiceCall 
{
   @Id 
   private String id; 

}


@Embeddable 
public class ServiceCall {

   @OneToMany(fetch=FetchType.LAZY)
   @JoinColumn(name="join_column_defined_on_customer_table")
   List getServiceCallHistory(); 
}

Update: putting FetchType.LAZY on the getServiceCallHistory() is a hint to the JPA provider to wait until you call getServiceCallHistory before it does another select to pull in that association.

Dus met de setup beschrijf ik als je customer.getLastServiceCall (). GetDate() het zal niet trekken in de ServiceCallHistory voordat de relatie lui is.

3
toegevoegd
Ik heb mijn antwoord bijgewerkt, vergeet alsjeblieft niet om te stemmen als je het antwoord nuttig vindt.
toegevoegd de auteur ams, de bron
bedankt. Ik heb mijn vraag bijgewerkt - Ik heb de velden van ServiceCall op de klant nodig zonder extra joins. Suggereert u dat u de ServiceCall-velden dupliceert: één exemplaar in het ingesloten exemplaar en een ander in de tabel Historisch?
toegevoegd de auteur Asaf, de bron

Wat je nodig hebt, is het volgende:

  • Een klantentiteit
  • Een insluitbare ServiceCall
  • Een HistoricalServiceCall-entiteit.

De klant moet een ingebed ServiceCall-veld bevatten (de laatste serviceaanvraag).

De HistoricalServiceCall-entiteit moet een ID, een ingesloten ServiceCall-veld (de gegevens van de HistoricalServiceCall) en mogelijk een ManyToOne-associatie met de klant hebben als u wilt dat de OneToMany bidirectioneel is.

De klant moet een OneToMany-koppeling hebben met HistoricalServiceCall.

1
toegevoegd
bedankt. op welke manier uw antwoord verschilt van ams?
toegevoegd de auteur Asaf, de bron
Ik ga je beide antwoorden combineren. Ik moet nog steeds de juiste relatie zien tussen ServiceCall en diens entiteit Geschiedenis
toegevoegd de auteur Asaf, de bron
Ja, ik begrijp dat. Ik ga een lui een-op-veel doen, of model de relatie net van de geschiedenis kant. nog steeds TBD.
toegevoegd de auteur Asaf, de bron
Ik zie niet in waarom ik een OneToMany toevoeg van ServiceCall aan HistoricalServiceCall in plaats van aan CustomerServiceCall, zoals ik suggereer. Bovendien verbiedt dit het opnieuw gebruiken van de ServiceCall die kan worden ingesloten in HistoricalServiceCall. Met het antwoord van ams moet u alle velden en methoden van ServiceCall binnen de HistoricalServiceCall-klasse dupliceren.
toegevoegd de auteur JB Nizet, de bron
Zelfs als u de koppeling in ServiceCall plaatst, blijft de koppeling tussen de klant en de HistoricalServiceCall. Een ingesloten object wordt alleen gebruikt om sommige velden samen te groeperen, maar het kan niet het doelwit van een koppeling zijn.
toegevoegd de auteur JB Nizet, de bron