2010-12-15 8 views
0

Ich habe einfach 3 Tabellen:Warum kann die dritte Tabelle nicht mit JPA TopLink Annotation verbunden werden?

Users 
-id 
-name 

Addresses 
-id 
-user_id //FK 
-location 

Phone 
-id 
-number 
-address_id //FK 
  • Benutzer können viele Adressen haben
  • Adressen viele Telefon

So haben kann, auf jede Entität Klasse angewendet Anmerkungen aussehen würde:

Benutzer

@OneToMany(cascade = CascadeType.ALL, mappedBy = "user") 
    private List<Addresses> addresses; 

Adressen

@ManyToOne() 
    @JoinColumn(name = "user_id") 
    private Users user; 

    @OneToMany(mappedBy = "address") 
    private List<Phone> phone; 

Telefon

@ManyToOne() 
    @JoinColumn(name = "address_id") 
    private Addresses address; 

Die obige Anmerkung sollte Beziehung erstellen:

users (1) ----- (n) addresses (1) ------ (n) phone 

Dann habe ich einige Test da ta in MySQL und versuchte, einen Test auszuführen, um zu sehen, ob das Abfrageergebnis, das "Benutzer" zurückgibt, einen Verweis auf Adressen und Telefon enthalten würde.

Ich habe versucht mit 2 Tabelle nur mit Benutzern und Adressen und bekam das Ergebnis in Ordnung.

Jetzt, dass ich "Telefon" -Tabelle, die dritte Tabelle ist, dann habe ich Fehler unten angezeigt. Ist das wirklich der richtige Weg, um 3 oder mehr Tische zu verbinden?

Prüfregeln

 try { 
      //get entity manager 
      String WEB_PU = "NoJSFPU"; 
      EntityManagerFactory factory =     Persistence.createEntityManagerFactory(WEB_PU); 
      EntityManager em = factory.createEntityManager(); 

      //run query 
      List<Users> usersList = em.createQuery("SELECT u FROM Users u").getResultList(); 

      //loop to print out each result 
      for(Users item : usersList) { 
       //display user info 
       System.out.println(item.getId() + " " + item.getFirstname()); 

       List<Addresses> addrs = item.getAddresses(); 
       for(Addresses ad : addrs) { 
        //display address info 
        System.out.println("Address:::" + ad.getLocation()); 

        List<Phone> pho = ad.getPhone(); 
        for(Phone p : pho) { 
        //display phone info 
        System.out.println("phone#" + p.getNumber()); 
        } 

       }//end inner for 
      }//end outer for 
       System.out.println("=========================="); 

      } 
      catch(Exception e) { 
       System.out.println("seriously wtf: " + e.toString()); 
       System.exit(1); 
      } 

Fehler

Exception Description: predeploy for PersistenceUnit [NoJSFPU] failed. 
Internal Exception: Exception [TOPLINK-7250] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException 
Exception Description: [class local.test.session.Addresses] uses a non-entity [class local.test.session.Phone] as target entity in the relationship attribute [private java.util.List local.test.session.Addresses.phone]. 
+2

Pssh, würde ich Benennen Sie Ihre Benutzer- und Adress-Tabellen als Benutzer und Adresse um. Verwenden Sie keine Pluralformen in Tabellennamen (auch nicht in Klassennamen von Entitätsklassen). – BalusC

+0

Hallo BalusC, lange Zeit zu sehen! Danke für den Hinweis, aber warum wird Singular für Tabellennamen verwendet? Ist es standardisierte Konvention? –

Antwort

1

habe ich herausgefunden. Muss mit @JoinTable Annotation angegeben werden.

Jetzt können Wenn ich den Test-Code, Daten aus allen drei Tabellen laufen erhalten: D

Adressen

@ManyToOne 
@JoinTable(name = "Addresses", joinColumns = {@JoinColumn(name="user_id", 
referencedColumnName = "user_id") }) 
private Users user; 

Telefon

@ManyToOne 
@JoinTable(name = "Phone", joinColumns = {@JoinColumn(name="address_id", 
referencedColumnName = "address_id") }) 
private Addresses address;