2011-10-23 17 views
9

İki tane basit fasulyem var - FatKid ve Hamburgers. Şimdi, benim için bilmediğim nedenlerden ötürü, sadece yedikleri hamburgeri değil, aynı zamanda hangi hamburgeri yiyen hamburgere de bakmam gerekiyor. Kodun üzerine!Hazırda bekleme ve H2 OneToMany çift yönlü eşleme için "Referential dürüstlük kısıtlaması ihlali"

FatKid.java

import java.util.List; 
import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 

@Table 
@Entity 
public class FatKid { 

    private int id; 
    private String name; 
    private List<Hamburger> hamburgers; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "FATKID_ID") 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 

    @Column 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumn(name="HAMBURGER_ID") 
    public List<Hamburger> getHamburgers() { 
     return hamburgers; 
    } 
    public void setHamburgers(List<Hamburger> hamburgers) { 
     this.hamburgers = hamburgers; 
    } 

} 

Hamburger.java

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

@Table 
@Entity 
public class Hamburger { 

    private int id; 
    private String description; 
    private FatKid whoDoneAteMe; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "HAMBURGER_ID") 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 

    @Column 
    public String getDescription() { 
     return description; 
    } 
    public void setDescription(String description) { 
     this.description = description; 
    } 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name="FATKID_ID") 
    public FatKid getWhoDoneAteMe() { 
     return whoDoneAteMe; 
    } 
    public void setWhoDoneAteMe(FatKid whoDoneAteMe) { 
     this.whoDoneAteMe = whoDoneAteMe; 
    } 

} 

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD//EN" 
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
    <session-factory> 
     <property name="hibernate.connection.driver_class">org.h2.Driver</property> 
     <property name="hibernate.connection.url">jdbc:h2:~/routesetting</property> 
     <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property> 

     <!-- JDBC connection pool (use the built-in) --> 
     <property name="connection.pool_size">1</property> 

     <!-- Enable Hibernate's automatic session context management --> 
     <property name="current_session_context_class">thread</property> 

     <!-- Disable the second-level cache --> 
     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 

     <!-- Echo all executed SQL to stdout --> 
     <property name="show_sql">true</property> 

     <!-- Drop and re-create the database schema on startup --> 
     <property name="hbm2ddl.auto">create-drop</property> 

     <mapping class="FatKid" /> 
     <mapping class="Hamburger" /> 

    </session-factory> 
</hibernate-configuration> 

bağımlılıkları

<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-core</artifactId> 
    <version>3.6.7.Final</version> 
</dependency> 

<dependency> 
    <groupId>com.h2database</groupId> 
    <artifactId>h2</artifactId> 
    <version>1.3.160</version> 
</dependency> 

<dependency> 
    <groupId>javassist</groupId> 
    <artifactId>javassist</artifactId> 
    <version>3.9.0.GA</version> 
</dependency> 

Kodun çalıştırmak

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 

public class OmNom { 

    private static final SessionFactory sessionFactory = buildSessionFactory(); 

    public static void main(String[] args) { 

     Session session = sessionFactory.openSession(); 

     session.beginTransaction(); 
     FatKid fk = new FatKid(); 
     fk.setName("Darrell"); 
     session.save(fk); 
     session.getTransaction().commit(); 

     session.beginTransaction(); 
     Hamburger hamburger_1 = new Hamburger(); 
     hamburger_1.setDescription("Juicy quarter pounder with cheese"); 
     hamburger_1.setWhoDoneAteMe(fk); 
     session.save(hamburger_1); 
     session.getTransaction().commit(); 

     session.beginTransaction(); 
     Hamburger hamburger_2 = new Hamburger(); 
     hamburger_2.setDescription("Ground buffalo burger topped with bacon and a sunny-side egg"); 
     hamburger_2.setWhoDoneAteMe(fk); 
     session.save(hamburger_2); 
     session.getTransaction().commit(); 

     sessionFactory.close(); 

    } 

    private static SessionFactory buildSessionFactory() { 
     try { 
      // Create the SessionFactory from hibernate.cfg.xml 
      return new Configuration().configure().buildSessionFactory(); 
     } 
     catch (Throwable ex) { 
      // Make sure you log the exception, as it might be swallowed 
      throw new ExceptionInInitializerError(ex); 
     } 
    } 

} 

Böylece çıkış (ve kesik yığın izleme)

Hibernate: insert into FatKid (FATKID_ID, name) values (null, ?) 
Hibernate: insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?) 
Hibernate: insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?) 
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not insert: [Hamburger] 
     ... 
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK43797FE95067143: PUBLIC.HAMBURGER FOREIGN KEY(HAMBURGER_ID) REFERENCES PUBLIC.FATKID(FATKID_ID)"; SQL statement: 
insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?) [23506-160] 
     ... 

ile son müşteri Yani ilk Hamburger kaydedilir fakat daha sonra ikinci darbeler. Her ikisi de FatKid'in kimliğini yabancı anahtar olarak kullanabilmelidir, ancak işe yaramaz. Herhangi bir anlayış büyük ölçüde takdir edilecektir.

sayesinde Kevin

cevap

6

Kişisel eşleştirmeleri bana garip görünüyor. İlişkinin her iki tarafında bir @JoinColumn var, her biri diğer tablonun birincil anahtarını işaret ediyor. Bu OneToMany ilişkisi gibi görünmüyor.

@OneToMany(cascade = CascadeType.ALL, mappedBy = "whoDoneAteMe") 
public List<Hamburger> getHamburgers() { 
    return hamburgers; 
} 

ve sonra diğer tarafında:

@ManyToOne(cascade = CascadeType.ALL) 
@JoinColumn(name = "fatkid_id") 
public FatKid getWhoDoneAteMe() { 
    return whoDoneAteMe; 
} 

Sen ayrıca çok kodunuzu optimize etmek mümkün olabilir

Sizin OneToMany ilişkinin sahibi söylemek gerekir. senin FatKid nesneleri Hamburger nesnelerin farkında ve basamaklı yapılandırılmış gibi, bunu yapabilirsiniz:

session.beginTransaction(); 
    FatKid fk = new FatKid(); 
    fk.setName("Darrell"); 

    Hamburger hamburger_1 = new Hamburger(); 
    hamburger_1.setDescription("Juicy quarter pounder with cheese"); 
    hamburger_1.setWhoDoneAteMe(fk); 
    fk.getHamburgers().add(hamburger1); 

    Hamburger hamburger_2 = new Hamburger(); 
    hamburger_2.setDescription("Ground buffalo burger topped with bacon and a sunny-side egg"); 
    hamburger_2.setWhoDoneAteMe(fk); 
    fk.getHamburgers().add(hamburger2); 

    session.save(fk); 
    session.getTransaction().commit(); 

    sessionFactory.close(); 

Yukarıdaki kod sadece bir operasyon taahhüt ile ve tek bir işlemde tam nesne grafiği kaydetmek gerekir.

+0

Çok teşekkür ederim, bu ekstra @JoinColumn'u kaldırarak mappedBy'yi ekledik. – Kevin