【问题标题】:@ManyToMany no entries in linking table@ManyToMany 链接表中没有条目
【发布时间】:2013-08-22 18:39:46
【问题描述】:

也许这里有人可以给我一个提示,错误可能出现在哪里(JSF 2.2,Glassfish 4.0):

  • 我有两个具有多对多关系的实体(参见示例)
  • 当我在 glassfish 中部署我的项目时,所有表(也是链接表)都会正确生成(在 persistence.xml 中启用创建表):TAGUSERWISH、TAGUSERWISH_WISH(链接表)、WISH
  • 当我执行持久化(参见示例)实体“wish”和“tagUserWish”时,会正确持久化,但是当我直接查看 mysql 表时,没有任何内容写入链接表。但是当我用 JPA 读出“wish”时,List<TagUserWish> 被填满了
  • 新会话一开始(重新部署)List<TagUserWish> 在使用 JPA 读出时也是空的

所有者实体:

@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 + " ]";
    }

}

实体 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+" ]";
    }     
}

我如何坚持:

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

还有愿望服务:

@Stateless
public class WishService implements Serializable{

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

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

【问题讨论】:

    标签: jsf jpa many-to-many entity jpa-2.0


    【解决方案1】:

    关系基于关系的所有者方而持续存在。双向关系的所有者是反面的mappedBy 值的所有者。在以下情况下,关系的所有者是 TagUserWish 实体中的 wishes 字段

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

    因为TagUserWish 的实例确实有空的wishes 集合,所以关系不会保持。问题可以通过在TagUserWish的实例中添加相关的Wish来解决,例如:

    ...
    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
    ...
    

    【讨论】:

    • 谢谢。这正是错误所在的位置。但也许我可以再问一个问题以便更好地理解:随后我尝试用@ManyToMany(mappedBy = "tags") 标记实体TagUserWish,用@ManyToMany(cascade = {CascadeType.ALL} ) 标记实体Wish,因为这样持久化的代码会更少,就像在我的示例中一样。但这没有用。 WISH_TAGUSERWISH 已创建,但没有插入任何内容。这不应该工作吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多