当我尝试运行以下代码时,我收到org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: safu.Publisher
异常:
public class SafuClient {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Publisher publisher = new Publisher("ABC", "ABC Co.");
Book book = new Book("1-932394-88-5", "Safu", publisher);
session.save(book);
session.getTransaction().commit();
}
}
我与书籍之间存在多对一的关系。书籍和出版商实体如下:
@Entity
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String isbn;
private String name;
@ManyToOne(cascade={CascadeType.PERSIST})
@JoinColumn(name="publisher_id")
private Publisher publisher;
public Book() {}
public Book(String isbn, String name, Publisher publisher) {
this.isbn = isbn;
this.name = name;
this.publisher = publisher;
}
}
@Entity
public class Publisher {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String code;
private String name;
public Publisher() {}
public Publisher(String code, String name) {
this.code = code;
this.name = name;
}
}
如果我将@ManyToOne(cascade={CascadeType.PERSIST})
替换为@ManyToOne(cascade={CascadeType.ALL})
实体中的Book
,一切正常。
有人可以解释为什么会这样吗?
答案 0 :(得分:1)
尝试session.persist(book);
这解决了问题而不是session.save(book);
答案 1 :(得分:1)
session.save(book)
方法的工作原理是从cascade={CascadeType.PERSIST}
实体中的@ManyToOne
注释中删除级联属性(Book
)并在发布商字段中添加@Cascade (value=CascadeType.SAVE_UPDATE)
代替。
@Cascade (value=CascadeType.SAVE_UPDATE)
使用Hibernate的原生注释。
按照更新的Book.java工作:
@Entity
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String isbn;
private String name;
@ManyToOne
@JoinColumn(name="publisher_id")
@Cascade(value=CascadeType.SAVE_UPDATE)
private Publisher publisher;
public Book() {}
public Book(String isbn, String name) {
this.isbn = isbn;
this.name = name;
}
public Book(String isbn, String name, Publisher publisher) {
this.isbn = isbn;
this.name = name;
this.publisher = publisher;
}
}