1

I have a couple of weeks starting with hibernate.

I have this code database

|       TABLE A               |       
-------------------------------
idA integer not null (PK)     |
name varchar(45) not null     |
lastname varchar(45) not null |


|       TABLE B               |       
-------------------------------
idB integer not null (PK)     |
name varchar(45) not null     |
lastname varchar(45) not null |


|       TABLE A_B             |       
-------------------------------
idA integer not null (PK)     |
idB integer not null (PK)     |

and these are my entities in java

@Entity
public class A{

@Id
private int id;

@Column
private String name;

@Column
private String lastName;

@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name="A_B", joinColumns={@JoinColumn(name="idA")}, inverseJoinColumns={@JoinColumn(name="idB")})
private List<B> ManyB;

//Getter and Setters

}


@Entity
public class B{

@Id
private int id;

@Column
private String name;

@Column
private String lastName;

@ManyToMany(mappedBy="ManyB", cascade={CascadeType.ALL})
private List<A> ManyA;

//Getter and Setters

}

I have 2 objects with many to many relationship and I have created the database in an intermediate table to make it in one to many relationship. I have several questions about this.

1 -. To add a record in the A_B table only lets me when I add objects B in the list declared in class A, if I do it the other way around, from class A by adding objects B I add in table A but not the A_B table.

. 2 - How do I delete or modify a record in the table A_B without having to delete or modify objects in Table A or B.

. 3 - When you get a list of all objects, for example I get the class A, I Returns a list and it contains A, and make an infinite recursively toString, this affects performance in memory or program?

Thanks attentive to your comments.

Elias Vargas
  • 1,126
  • 1
  • 18
  • 32

2 Answers2

2

Lets take your example of adding a record to the A_B table a bit more concrete. Take a User object and a Skill object. Every user has many skills, but Skill also has a List of users called skill-owners. Hence, User is your table A, Skill is your table B and Skill-owner is the many-to-many generated table A_B.

Now, when I want to add a skill to an owner, it automatically becomes a skill-owner as well. In a JPA-setting you have to add the property on both sides. Concretely, you have to add the skill to the skillset of the user and the user to the skill-owners. Thus, in your service class you should address both repositories.

The Skill Entity:

@Entity
public class Skill {
    @Id
    @GeneratedValue
    @Column(name = "skillId")
    private long id;
    private String skill;
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "userSkillsList",
            joinColumns = {@JoinColumn(name = "skillId")},
            inverseJoinColumns = {@JoinColumn(name = "username")})
    private Set<User> skillOwners;

}

The user Entity:

@Entity
public class User {
    @Id
    private String username;
    @ManyToMany(fetch = FetchType.LAZY,
            mappedBy = "skillOwners")
    private List<Skill> skillsList = new LinkedList<Skill>();
}    

And to add a skill to a user you can add the following to the Skill entity, or where you see most appropriate:

public void addSkillToUser(Long s) {
    Skill skill = skillRepository.findOne(s);
    selectedUser.addSkill(skill);
    skill.addSkillOwner(selectedUser);
    userRepository.save(selectedUser);
    skillRepository.save(skill);
}

And to delete:

public void deleteSkill(Skill skill) {
    selectedUser.deleteSkill(skill);
    skill.removeSkillOwner(selectedUser);
    skillRepository.save(skill);
    userRepository.save(selectedUser);
}

Concerning your issues with deleting an item on a list, you should look into the Cascading annotation of JPA/Hibernate. With the right annotation you can Cascade only on update and for instance not on removal. So if on User.skillsList you set cascade = CascadeType.UPDATE it should only change properties of the skill on update. Read more about the CascadeType enum here: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html#objectstate-transitive .

Your third question I don't fully understand, but have you added a custom toString method to the A-class?

jvdp
  • 149
  • 8
  • Hi, thanks for the reply, I clarified enough. The last question I want to know is if it somehow affects the performance of my program to get the list of objects contained in each other infinitely. – Elias Vargas Jul 29 '14 at 21:57
  • Well, like I tried to show with the example, there is not really an infinite recursion. Anyway, you can tweak your performance with setting `fetch = FetchType.LAZY` in the ManyToMany annotation. This way it will not fetch the full objects of the list when the Skill or User object is fetched. The opposite is Eager, for more info you should check the hibernate documentation or this [example](http://howtoprogramwithjava.com/hibernate-eager-vs-lazy-fetch-type/). – jvdp Jul 30 '14 at 07:28
  • hello friend, look now when I try to get the associated list sends me the following error: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: – Elias Vargas Aug 01 '14 at 03:56
  • Read the following SO questions and try to understand it: [Difference Lazy and Eager in JPA](http://stackoverflow.com/questions/2990799/difference-between-fetchtype-lazy-and-eager-in-java-persistence) and on the [LazyInitializationError](http://stackoverflow.com/questions/11746499/how-to-resolve-failed-to-lazily-initialize-a-collection-of-role-exception). It basically has to do with the databasesession. If you initialize your connection again you can fetch the children. Or you decide to Eager load them, whichever is more appropriate. – jvdp Aug 01 '14 at 09:08
0

When you want to establish many-to-many relationship between two tables, create an intermediate table with one-to-one entry. So your A-B table will have one to one insertion of data. and use normal queries to insert and delete records from your A-B table. Make all of your transactions through this A-B table.

enter image description here

Vivek Mishra
  • 1,772
  • 1
  • 17
  • 37