Search code examples
hibernatepostgresqlpersistence

hibernate persist two objects simultaneously


I have two objects which have OneToOne relation between them: Project and Donation. Project object relays some logic to Donation object that is situated inside Project object (donations table shopuld be filled when projects is filled).My aim is to make Donation object to be persisted when Project is persisted. My classes:

Project.java

@Entity
@Table(name="projects")
public class Project{

    private int id;
    private String name;

    public Donation donation;

    public Project() {}

    public Project(String name, Donation donation) {
        this.name = name;
        this.donation = donation;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="project_id")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    @Column(name="project_name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @OneToOne
    @JoinColumn(name = "project_id")
    public DonationLogic getDonation() {
        return donation;
    }

    public void setDonation(DonationLogic donation) {
        this.donation = donation;
    }
}

Donation.class

@Entity
@Table(name="donations")
public class Donation {
    private int totalAmount;
    private int daysLeft;
    private double collectAmount;
    private int id;
    private Project project;

    public Donation() {}

    public Donation(int totalAmount, int daysLeft) {
        if(totalAmount <= 0 || daysLeft <= 0) {
            throw new IllegalArgumentException();
        }
        this.totalAmount = totalAmount;
        this.daysLeft = daysLeft;
        this.collectAmount = 0.0;
    }

    public Donation(int totalAmount, int daysLeft, double collectedamount) {
        if(totalAmount <= 0 || daysLeft <= 0) {
            throw new IllegalArgumentException();
        }
        this.totalAmount = totalAmount;
        this.daysLeft = daysLeft;
        this.collectAmount = collectedamount;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="donation_id")
    public int getId() {
        return id;
    }

    @OneToOne
    @JoinColumn(name="donation_project_id")
    public Project getProject() {
        return project;
    }

public void setProject(Project project) {
        this.project = project;
    }
//other getters/ setters
}

Here I want to persist Project but with Donation as well. But for now it does not work((( Only projects table is filled. Not donations table. Is it possible to persist them simultaneously - donations table filled when projects filled?

Main.java

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        SessionFactory sessionfactory = (SessionFactory) context.getBean("sessionFactory");
        Session session = sessionfactory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Donation donation = new Donation(10000, 50);
        Project project1 = new Project("sport arena", "arena in Kiev",  donation);
        session.persist(project1);//only projects table is persisted. Not donations. 
}

In donations table foreign key is column donation_project_id. In projects - primary key project_id.


Solution

  • You need to add cascade type to your annotation like this :

    @OneToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "project_id")
    public DonationLogic getDonation() {
        return donation;
    }
    

    Hibernate documentation about it

    UPDATE:

    In a bi-directional association, one side of the of the relation must own the association. This is a good example.