2011-10-23 29 views
9

Vì vậy, tôi có hai hạt đơn giản - FatKid và Hamburgers. Bây giờ, vì những lý do không được biết đến với tôi, tôi cần có khả năng không chỉ tìm kiếm tất cả những người hamburger mà ai đó ăn, mà còn có thể ăn những chiếc bánh hamburger đặc biệt. Vào mã!Hibernate và H2 "Vi phạm ràng buộc toàn vẹn tham chiếu" đối với ánh xạ hai chiều OneToMany

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> 

phụ thuộc

<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> 

client

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); 
     } 
    } 

} 

Vì vậy, khi tôi chạy đoạn code tôi kết thúc với kết quả (và cắt ngắn stack trace)

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] 
     ... 

Vì vậy, Hamburger đầu tiên được lưu nhưng sau đó nó thổi lên ngày thứ hai. Cả hai sẽ có thể sử dụng id của FatKid là khóa ngoại của họ nhưng nó dường như không hoạt động. Bất kỳ cái nhìn sâu sắc sẽ được đánh giá rất nhiều.

Xin cảm ơn, Kevin

Trả lời

6

Ánh xạ của bạn trông lạ với tôi. Bạn có một @JoinColumn ở cả hai bên của mối quan hệ, mỗi trỏ đến khóa chính của bảng kia. Điều đó dường như không phải là mối quan hệ OneToMany.

OneToMany của bạn nên thông báo cho chủ của mối quan hệ:

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

và sau đó ở phía bên kia:

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

Bạn có thể có thể để tối ưu hóa mã của bạn hơn nữa quá. Như đối tượng FatKid bạn nhận thức của các đối tượng Hamburger và bạn đã cấu hình tầng, bạn có thể làm:

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(); 

Đoạn mã trên nên lưu đồ thị đối tượng hoàn chỉnh chỉ với một cam kết hoạt động và trong một giao dịch duy nhất.

+0

Cảm ơn bạn rất nhiều, xóa thêm @JoinColumn đó và thêm mappedBy đã làm cho nó hoạt động. – Kevin

Các vấn đề liên quan