timmornYE
timmornYE

Reputation: 728

@ManyToMany no entries in linking table

Perhaps someone here can give me a tip where the error could be situated (JSF 2.2, Glassfish 4.0):

Owner entity:

@Entity
public class Wish implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String subject;
    private String abstractT;

    @OneToOne
    private User user;

    @ManyToMany(mappedBy = "wishes", cascade = {CascadeType.ALL} )
    private List<TagUserWish> tags = new LinkedList<>();

    public void addTag(TagUserWish tag){
        tags.add(tag);
    }

    public void setTags(List<TagUserWish> tags) {
        this.tags = tags;
    }       

    public void removeTag(TagUserWish tag){
        tags.remove(tag);
    }

    public List<TagUserWish> getTags(){
        return tags;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getAbstractT() {
        return abstractT;
    }

    public void setAbstractT(String abstractT) {
        this.abstractT = abstractT;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }


    public Long getId() {
        return id;
    }

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

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Wish)) {
            return false;
        }
        Wish other = (Wish) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "eu.citato.main.model.Wish[ id=" + id + " ]";
    }

}

Entity 2:

@Entity
public class TagUserWish implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;        
    private String name;

    public TagUserWish() {
    }          

    public TagUserWish(String name) {
        this.name = name;
    }          

    @ManyToMany
    private List<Wish> wishes = new LinkedList<>();

    public void addWish(Wish wish){
        wishes.add(wish);
    }

    public void setWishes(List<Wish> wishes) {
        this.wishes = wishes;
    }       

    public void removeWish(Wish tag){
        wishes.remove(tag);
    }

    public List<Wish> getWishes(){
        return wishes;
    }

    public String getName() {
        return name;
    }

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

    public Long getId() {
        return id;
    }

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


    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof TagUserWish)) {
            return false;
        }
        TagUserWish other = (TagUserWish) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "eu.citato.main.model.Tag[ id=" + id + ", name="+name+" ]";
    }     
}

How I persist it:

@javax.inject.Named 
@SessionScoped
public class WishPM implements Serializable {

    @EJB
    private WishService wls;

    public void commitEditWish(){        
        List<TagUserWish> selTags = new ArrayList<>();
        selTags.add(new TagUserWish("Tag1"));
        selTags.add(new TagUserWish("Tag2"));
        currentWish = new Wish();
        currentWish.setSubject("wishSubject");
        currentWish.setAbstractT("wishAbstract");
        currentWish.setTags(selTags);
        wls.createWish(currentWish);
    }
}

And the wish Service:

@Stateless
public class WishService implements Serializable{

    @PersistenceContext(unitName = "WishlistPU")
    private EntityManager em;

    public void createWish(Wish entity){
        em.persist(entity);
    }
}

Upvotes: 0

Views: 137

Answers (1)

Mikko Maunu
Mikko Maunu

Reputation: 42114

Relationships are persisted based to the owner side of relationship. Owner of the bidirectional relationship is one that is value of mappedBy in inverse side. In following case owner of the relationship is wishes field in TagUserWish entity

@ManyToMany(mappedBy = "wishes", cascade = {CascadeType.ALL} )
private List<TagUserWish> tags = new LinkedList<>();

Because instance of TagUserWish do have empty wishes collection, relationship is not persisted. Problem can be solved by adding related Wish to the instance of TagUserWish, for example as follows:

...
TagUserWish tuw1 = new TagUserWish("Tag1")
TagUserWish tuw2 = new TagUserWish("Tag2")

selTags.add(tuw1);
selTags.add(tuw2);

currentWish = new Wish();
tuw1.addWish(currentWish); //setting to owner side of relationship
tuw2.addWish(currentWish); //setting to owner side of relationship
...

Upvotes: 1

Related Questions