-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Hibernate mapping that follow rules of normal RDBMS
PostPosted: Sun Dec 04, 2016 2:03 pm 
Newbie

Joined: Thu Mar 15, 2012 2:48 pm
Posts: 13
Dear guys,

I didn't used java for many years, and even at that time i never been an expert, and now i came back to fulfill a friend requirment in java (as i my self like java developer, i like java more than the language i work in (C#)).

Make story short, i have several entities, Person, Position, Wage, Building and Work.

Each work owns a foreign key of both person and building.
Each Person own a foreign key from Position.
Each Position share it's Id With Lot of Wages (Each wage own a forein key of position) -> so in different dates, i can track the wage of that person.

The issue i have, first my db was a mess though it's a 1-to-m mapping, i had m to m tables too, then someone told me that i have to use mappedBy and i did it, the DB went to good shape, so i write my code down and deep down, till my user input was complete, and i gave it to the person of need.

then i went to wrote delete solution, but... when i tried to delete my entity it generated error, then i tried, then i used cascade all on @ManyToOne, it generate "...persist..." or some thing like that error, i didn't got what it said due my lack in english, but it had that word in it.

then i moved cascade to other side (@OneToMany), now it delete everything.

What i want:
when i delete a model that someone has it's foreign key, system generate error, like sql server, or my sql, but not for other, if no one has it's foreign key, it should get deleted.
Beside this i have one exception, relation between position and wage, should also be controlled from position entity.

I'm using Spring Boot as my base structure, and i use JpaRepository.

Thank you for your time.



My Entities:

Building
Code:
package hassan.personnel.managment.models.entities;

import hassan.personnel.managment.models.interfaces.ViewModel;
import hassan.personnel.managment.models.vm.BuildingVm;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Hassan on 11/16/2016.
*/
@Entity
@Table(name = "Building")
public class Building implements ViewModel {
    public Building(String name) {
        this.name = name;
    }

    public Building() {
        this.works = new ArrayList<>();
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false, length = 50)
    private String name;

    @OneToMany(mappedBy = "building")
    private List<Work> works;

    public BuildingVm getViewModel(){
        BuildingVm buildingVm = new BuildingVm();
        buildingVm.setId(this.getId());
        buildingVm.setName(this.getName());
        buildingVm.setWorks(null);

        return buildingVm;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public List<Work> getWorks() {
        return works;
    }

    public void setWorks(List<Work> works) {
        this.works = works;
    }
}


Person
Code:
package hassan.personnel.managment.models.entities;

import hassan.personnel.managment.models.interfaces.ViewModel;
import hassan.personnel.managment.models.vm.PersonVm;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Hassan on 11/16/2016.
*/
@Entity
@Table(name = "Person")
public class Person implements ViewModel {

    public Person(){
        this.works = new ArrayList<>();
    }

    public Person(String firstname, String lastname, Position position) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.position = position;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false, length = 50)
    private String firstname;

    @Column(nullable = true, length = 50)
    private String lastname;

//    @Column(name = "position_id")
//    private int positionId;

    @ManyToOne
//    @JoinColumn(nullable = false, foreignKey = @ForeignKey(name = "position_id"))//referencedColumnName = "positionId")-->Name of the PK
    private Position position;

    @OneToMany(mappedBy = "person")
    private List<Work> works;

    public PersonVm getViewModel() {
        PersonVm personVm = new PersonVm();
        personVm.setId(this.getId());
        personVm.setFirstname(this.getFirstname());
        personVm.setLastname(this.getLastname());

        personVm.setPosition(this.getPosition() != null ? this.getPosition().getViewModel() : null);
        personVm.setWorks(null);

        return personVm;
    }

    public int getId() {
        return id;
    }

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

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

//    public int getPositionId() {
//        return positionId;
//    }
//
//    public void setPositionId(int positionId) {
//        this.positionId = positionId;
//    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

    public List<Work> getWorks() {
        return works;
    }

    public void setWorks(List<Work> works) {
        this.works = works;
    }
}


Position
Code:
package hassan.personnel.managment.models.entities;

import hassan.personnel.managment.models.interfaces.ViewModel;
import hassan.personnel.managment.models.vm.PositionVm;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Hassan on 11/16/2016.
*/
@Entity
@Table(name = "Position")
public class Position implements ViewModel {

    public Position(){
        personnel = new ArrayList<Person>();
        wages = new ArrayList<Wage>();
    }

    public Position(String title) {
        this.title = title;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false, length = 50)
    private String title;

    @OneToMany(mappedBy = "position")
    private List<Wage> wages;

    @OneToMany(mappedBy = "position")
    private List<Person> personnel;

    public PositionVm getViewModel() {
        PositionVm positionVm = new PositionVm();
        positionVm.setId(this.getId());
        positionVm.setTitle(this.getTitle());
        positionVm.setPersonnel(null);
        positionVm.setWages(null);

        return positionVm;
    }

    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

//    public int getWageId() {
//        return wageId;
//    }
//
//    public void setWageId(int wageId) {
//        this.wageId = wageId;
//    }

    public List<Wage> getWages() {
        return wages;
    }

    public void setWages(List<Wage> wages) {
        this.wages = wages;
    }

    public List<Person> getPersonnel() {
        return personnel;
    }

    public void setPersonnel(List<Person> personnel) {
        this.personnel = personnel;
    }
}


Wage
Code:
package hassan.personnel.managment.models.entities;

import hassan.personnel.managment.models.interfaces.ViewModel;
import hassan.personnel.managment.models.vm.WageVm;

import javax.persistence.*;
import java.util.Calendar;
import java.util.Date;

/**
* Created by Hassan on 11/16/2016.
*/
@Entity
@Table(name = "Wage")
public class Wage implements ViewModel {

    public Wage(){
    }

    public Wage(Calendar startDate, double price, Position position) {
        this.startDate = startDate;
        this.price = price;
        this.position = position;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Calendar startDate;

    @Column(nullable = true)
    private double price;

//    @Column(name = "position_id")
//    private int postionId;

    @ManyToOne
    //    @JoinColumn(nullable = false, foreignKey = @ForeignKey(name = "wage_id"))
    private Position position;

    public WageVm getViewModel() {
        WageVm wageVm = new WageVm();
        wageVm.setId(this.getId());
        wageVm.setStartDate(this.getStartDate());
        wageVm.setPrice(this.getPrice());
        wageVm.setPosition(this.getPosition() != null ? this.getPosition().getViewModel() : null);

        return wageVm;
    }

    public int getId() {
        return id;
    }

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

    public Calendar getStartDate() {
        return startDate;
    }

    public void setStartDate(Calendar startDate) {
        this.startDate = startDate;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

//    public int getPostionId() {
//        return postionId;
//    }
//
//    public void setPostionId(int postionId) {
//        this.postionId = postionId;
//    }
}


Work
Code:
package hassan.personnel.managment.models.entities;

import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;
import hassan.personnel.managment.models.interfaces.ViewModel;
import hassan.personnel.managment.models.vm.WorkVm;

import javax.persistence.*;
import java.util.GregorianCalendar;

/**
* Created by Hassan on 11/16/2016.
*/
@Entity
@Table(name = "Work")
public class Work implements ViewModel {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private int workPerDay;

    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Calendar date;

//    @Column(name = "person_id")
//    private int personId;
//
//    @Column(name = "building_id")
//    private int buildingId;

    @ManyToOne
//    @JoinColumn(nullable = false, foreignKey = @ForeignKey(name = "person_id"))
    private Person person;

    @ManyToOne
//    @JoinColumn(nullable = false, foreignKey = @ForeignKey(name = "building_id"))
    private Building building;

    public WorkVm getViewModel() {
        WorkVm workVm = new WorkVm();
        workVm.setId(this.getId());
        workVm.setDate(this.getDate());
        workVm.setWorkPerDay(this.getWorkPerDay());

        workVm.setBuilding(this.getBuilding() != null ? this.getBuilding().getViewModel() : null);
        workVm.setPerson(this.getPerson() != null ? this.getPerson().getViewModel() : null);

        return workVm;
    }


    public long getId() {
        return id;
    }

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

    public int getWorkPerDay() {
        return workPerDay;
    }

    public void setWorkPerDay(int workPerDay) {
        this.workPerDay = workPerDay;
    }

    public java.util.Calendar getDate() {
        return date;
    }

    public void setDate(java.util.Calendar date) {
        this.date = date;
    }

    public String getPersianDate() {
        ULocale local = new ULocale("fa_IR@calendar=persian");
        Calendar persianCalendar = Calendar.getInstance(local);
        persianCalendar.clear();

        java.util.Calendar gc = GregorianCalendar.getInstance();
        gc.set(2016, java.util.Calendar.JUNE, 30);

        persianCalendar.setTime(gc.getTime());

        return "" + persianCalendar.get(Calendar.YEAR)
                + persianCalendar.get(Calendar.MONTH)
                + persianCalendar.get(Calendar.DAY_OF_MONTH);
    }

    //    public int getPersonId() {
//        return personId;
//    }
//
//    public void setPersonId(int personId) {
//        this.personId = personId;
//    }
//
//    public int getBuildingId() {
//        return buildingId;
//    }
//
//    public void setBuildingId(int buildingId) {
//        this.buildingId = buildingId;
//    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Building getBuilding() {
        return building;
    }

    public void setBuilding(Building building) {
        this.building = building;
    }
}


Top
 Profile  
 
 Post subject: Re: Hibernate Mapping That Follow Rules of normal RDBMS
PostPosted: Mon Dec 05, 2016 1:04 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
I see you have many questions that are easily answered by reading our User Guide. Most of all, I think you should be synchronizing both ends of the association.

As fo cascading, you should never cascade from a ManyToOne association because cascading only makes sense from parent to child entities. Check out this article for more info.


Top
 Profile  
 
 Post subject: Re: Hibernate mapping that follow rules of normal RDBMS
PostPosted: Mon Dec 05, 2016 10:23 am 
Newbie

Joined: Thu Mar 15, 2012 2:48 pm
Posts: 13
i came to same place before i could fixed mappedBy and test cascade, the person who helped me fixed my mapping didn't told me everything, he said i should look at 2 part, one of them where that place, maybe it's my lack in english, but these annotation, are all to help remove more data when we remove something, and if i don't use them , i cannot even delete last child under some relationship, who no other node has reference to it. i want it to generate error where the node is referenced by someone, but not to delete when it is the one who reference....

Currently (under this configuration) i do delete something, and poof, the corresponding item property just become null, instead of generating error due to foreign key.


Top
 Profile  
 
 Post subject: Re: Hibernate mapping that follow rules of normal RDBMS
PostPosted: Mon Dec 05, 2016 11:25 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
But the DB should prevent you from deleting a row which is referenced by some other FK in some other table.


Top
 Profile  
 
 Post subject: Re: Hibernate mapping that follow rules of normal RDBMS
PostPosted: Mon Dec 05, 2016 11:35 am 
Newbie

Joined: Thu Mar 15, 2012 2:48 pm
Posts: 13
that's what i'm conserned about...
before puting cascade, i couldn't delete any, when they shared simple relationship... yes they had relation, but for example if work has key of person, i should be able to delete work, but not building, but i couldn't delete any. after i put cascade, now i can delete the building, and it nullify the work reference to the building...

the familty member i talked about, asked me to change an integer to floating point... and i had delete half way, so he press delete after last update (which was not available in older version, and also yet incomplete), and destroyed part of data... he wanted to remove unlinked refrerences, but also removed some referenced one too :|


Top
 Profile  
 
 Post subject: Re: Hibernate mapping that follow rules of normal RDBMS
PostPosted: Mon Dec 05, 2016 3:43 pm 
Newbie

Joined: Thu Mar 15, 2012 2:48 pm
Posts: 13
It work now

Thnak for your time


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.