hibernatejpajpa-2.0cascadehibernate-cascade

Unidirectional ManyToOne: Why transient instance saved with CascadeType.ALL but not CascadeType.PERSIST


I am getting org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: safu.Publisher exception when I try to run the following code:

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

    }
}

I have a Many-to-One relationship from Book to Publisher. Book and Publisher entities follows:


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

}

If I replace @ManyToOne(cascade={CascadeType.PERSIST}) with @ManyToOne(cascade={CascadeType.ALL}) in the Book entity everything works just fine.

Could somebody explain why is it happening?


Solution

  • Try session.persist(book); this solves the problem instead of session.save(book);