使用@JoinTable时的org.hibernate.exception.ConstraintViolationException

时间:2016-05-18 14:32:34

标签: database hibernate jpa orm foreign-keys

这是我的数据库:

------------       ----------------------       ------------
|   NEWS   |       |     NEWS_IMAGE     |       |  IMAGE   |
------------       ----------------------       ------------
| id | text|       | id_news | id_image |       | id | URL |
------------       ----------------------       ------------
  |                      |       |                |
  <-<-<-<-<-<- Foreign Key       Foreign Key ->->->

在对象新闻中,我有List对象图片。这是我的绘图系统:

@Entity
@Table(name = "news")
class News{

   @Id
   @GeneratedValue
   @Column(name = "id")
   private long id;

   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
   @JoinTable(name = "news_image",
              joinColumns = { @JoinColumn(name = "id_news")},
              inverseJoinColumns = { @JoinColumn(name = "id_image")})   
              private List<Image> images = new ArrayList<Image>();}

这是图像

的对象
@Entity
@Table(name = "image")
public class Image {

   @Id
   @Column(name = "id")
   @GeneratedValue
   private long id;

   @Column(name = "URL")
   private String URL;
}

这是我删除对象图像的方式:

News news  = org.hibernate.SessionFactory.get(News.class, id);
Image image = news.getImages().get(0);  
org.hibernate.SessionFactory.getCurrentSessionFactory().delete(image);

当我尝试从表图片中删除图片时出现此错误:

Could not execute JDBC batch update;
SQL [delete from image where id=?];
constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException:
Could not execute JDBC batch update.

如果我将表 news_image 中的外键删除到表图像,一切正常; Hibernate能够首先删除表格 news_image 中的记录,然后删除表格图像内的记录。 我该怎么办?我应该删除那个外键吗?我是否在映射时出错,这就是我收到错误的原因?

提前感谢。

2 个答案:

答案 0 :(得分:1)

正如您的映射所示,ImageNews的关联一无所知,因此Hibernate永远不会删除NEWS_IMAGE关联表中的相应记录,因为它对此一无所知它。

要解决此问题,您可以按以下方式更新代码:

//News is managing the association to Image and has Cascade options defined
//so we need to update and merge the News instance
News news  = org.hibernate.SessionFactory.get(News.class, id);
Image image = news.getImages().get(0);  
news.getImages().remove(image);
org.hibernate.SessionFactory.getCurrentSessionFactory().saveOrUpdate(news);

或者您可以更新映射,以便Image了解关联并按以前的步骤继续:

新闻:

@Entity
@Table(name = "news")
class News{

   @Id
   @GeneratedValue
   @Column(name = "id")
   private long id;

   @OneToMany(mappedBy = "news", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
   private List<Image> images = new ArrayList<Image>();
}

图像:

@Entity
@Table(name = "image")
public class Image {

   @Id
   @Column(name = "id")
   @GeneratedValue
   private long id;

   @Column(name = "URL")
   private String URL;

   @ManyToOne( cascade = CascadeType.DELETE)
   @JoinTable(name = "news_image",
              joinColumns = { @JoinColumn(name = "id_image")},
              inverseJoinColumns = { @JoinColumn(name = "id_news")})   
   private News news;

}

答案 1 :(得分:0)

您需要先从连接表中删除,然后才能从子表中删除。

import Foundation

class List {
    let name: String
    var movies: [String] = []

    init(name: String){
        self.name = name
    }

    func printList() {
        print("Movie List: \(name)")
        for movie in movies{
            print(movie)
        }
        print("\n")
    }
}


class User {
    var lists: [String: List] = [:]//****

    func addList(list: List){
        lists[list.name] = list
    }

    func listForName(name: String)-> List? {
        print(lists[name]?.movies)
        return lists[name]
    }

}

//create user
let jane = User()
let john = User()
let people = User()

//create list
var johnActionMovie = List(name: "ActionJhon")
var janeActionMovie = List(name: "ActionJane")
var sharedMovie = List(name: "SharedMovie")
var publicIntrest = sharedMovie

//call addList(_:) method on user object
jane.addList(janeActionMovie)
john.addList(johnActionMovie)

jane.addList(sharedMovie)
john.addList(sharedMovie)
people.addList(publicIntrest)


//private part appending
jane.lists["ActionJane"]?.movies.append("janeA")
jane.lists["ActionJane"]?.movies.append("janeB")
jane.lists["ActionJane"]?.movies.append("janeC")


john.lists["ActionJhon"]?.movies.append("johnA")
john.lists["ActionJhon"]?.movies.append("johnB")
john.lists["ActionJhon"]?.movies.append("johnB")

//Shared part appending
john.lists["SharedMovie"]?.movies.append("shareA")
jane.lists["SharedMovie"]?.movies.append("shareB")
people.lists["SharedMovie"]?.movies.append("shareC")


//print out the result
john.listForName("ActionJhon")
john.listForName("SharedMovie")

jane.listForName("ActionJane")
jane.listForName("SharedMovie")

people.listForName("SharedMovie")


//further check
print(jane.lists["ShareMovie"] === people.lists["ShareMovie"])
print(jane.lists["ActionJane"] === john.lists["ActionList"])