2016-09-12 6 views
3

を失敗した私は、データベースにオブジェクトを保存しようとしているとき、私はエラーを得た:Hibernateは子行を追加または更新できません:外部キー制約が

java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`smartphones`.`smartphone`, CONSTRAINT `fk_smartphone_resolution1` FOREIGN KEY (`resolution_id`) REFERENCES `resolution` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) 


まず最初は、私は間違った名前を持っていますSmartphoneクラスの参考列の私はチェックし、それはよく見えます。おそらく誰かがこの問題の理由を理解しているのだろうか?

ショートデータベースのスクリーンショット

enter image description here

スマートフォンテーブル

CREATE TABLE IF NOT EXISTS `smartphones`.`smartphone` (
     `id` INT(11) NOT NULL AUTO_INCREMENT, 
     `name` VARCHAR(45) NULL DEFAULT NULL, 
     `resolution_id` INT(11) NOT NULL, 
       ...other 
     PRIMARY KEY (`id`, `resolution_id`), 
     UNIQUE INDEX `id_UNIQUE` (`id` ASC), 
     INDEX `fk_smartphone_resolution1_idx` (`resolution_id` ASC), 
     CONSTRAINT `fk_smartphone_resolution1` 
     FOREIGN KEY (`resolution_id`) 
     REFERENCES `smartphones`.`resolution` (`id`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION) 

Smartphoneクラスが、1つの関係オブジェクトとを作成するためのSQLスクリプトを実行します。

package com.project.model; 

import javax.persistence.*; 

@Entity 
public class Smartphone { 
    private int id; 
    private String name; 
    private Resolution resolutionId; 

    @Id 
    @Column(name = "id") 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @Basic 
    @Column(name = "name") 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST) 
    @JoinColumn(name = "resolution_id", referencedColumnName = "id", nullable = false) 
    public Resolution getResolutionId() { 
     return resolutionId; 
    } 

    public void setResolutionId(Resolution resolutionId) { 
     this.resolutionId = resolutionId; 
    } 
} 

[編集:スマートフォンの機種を解析し、データベースに保存]

@RequestMapping(value = { "apple" }, method = RequestMethod.GET) 
    public String parseApple(ModelMap model) { 

     try { 
      String appleData = Utilities.getResourceAsString(this, "json/apple.json"); 

      JSONArray array = new JSONArray(appleData); 

      Session session = sessionFactory.openSession(); 
      Transaction transaction = session.beginTransaction(); 

      for (int i = 0; i < array.length(); i++) { 
       Smartphone smartphone = new Smartphone(); 

       String resolutionValue = array.getJSONObject(i).getString("resolution"); 
       String resolution_w = resolutionValue.split(" ")[0]; 
       String resolution_h = resolutionValue.split(" ")[2]; 
       Resolution resolution = new Resolution(); 
       resolution.setHeight(Integer.valueOf(resolution_h)); 
       resolution.setWidth(Integer.valueOf(resolution_w)); 
       resolution.setTypeId(typeService.findByCode(session, Resolution.serialId)); 
       session.save(resolution); 

       smartphone.setResolutionId(resolution); 
       //other 

       session.save(smartphone); 
       break; 
      } 
      transaction.commit(); 
      sessionFactory.close(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return "index"; 
    } 

[編集:追加]解像度クラス:

@Entity 
public class Resolution { 
    public static final int serialId = 106; 

    private int id; 
    private Integer height; 
    private Integer width; 
    private Type typeId; 
    private Collection<Smartphone> resolutionId; 

    @Id 
    @Column(name = "id") 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @Basic 
    @Column(name = "height") 
    public Integer getHeight() { 
     return height; 
    } 

    public void setHeight(Integer height) { 
     this.height = height; 
    } 

    @Basic 
    @Column(name = "width") 
    public Integer getWidth() { 
     return width; 
    } 

    public void setWidth(Integer width) { 
     this.width = width; 
    } 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name = "type_id", referencedColumnName = "id", nullable = false) 
    public Type getTypeId() { 
     return typeId; 
    } 

    public void setTypeId(Type typeId) { 
     this.typeId = typeId; 
    } 

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(mappedBy = "resolutionId") 
    public Collection<Smartphone> getResolutionId() { 
     return resolutionId; 
    } 

    public void setResolutionId(Collection<Smartphone> resolutionId) { 
     this.resolutionId = resolutionId; 
    } 
} 
+0

「スマートフォン」を保存すると、「解像度」が参照されるのはdbの永続エンティティである必要があります。 – kuhajeyan

+0

はい私はsession.save()を使用しています。新しいオブジェクトを保存するために新しいトランザクションを使用する必要がありますか?チェックしてください。私はソースコードを追加しました。 – Beata92

+0

私にはうまく見える – kuhajeyan

答えて

1

ほとんど良好です。以下のResolutionクラスおよび類似のコードの上にgetId()メソッドを追加する必要があります。おそらくあなたのresolutionオブジェクトは、メソッド呼び出しを保存した後に常に0を返します。idです。

@Column(name = "id", unique = true, nullable = false) 
@GeneratedValue(strategy = GenerationType.AUTO) 
2

あなたはresolutionadd/update行しようとしていますsmartphoneに格納されている値に基づいて、idフィールドに有効な値がありません。
最初に行をresolutionテーブルに挿入する必要があります。

+0

はい私は 'session.save()'を使用しています。新しいオブジェクトを保存するために新しいトランザクションを使用する必要がありますか? – Beata92

関連する問題