Hibernate - 带有附加列的链接表 - 在一个事务中保存

时间:2010-08-20 06:22:33

标签: java hibernate join

我正在学习Hibernate,只读了“Java Persistance with Hibernate”一书中的“7.2.3添加列连接表”一章。我的目标是在一个事务中保存Item,Category和CategorizedItem。

那里有一个构造函数(第305页):

public CategorizedItem(String username, Category category, Item item) {
    // Set fields
    this.username = username;

    this.category = category;
    this.item = item;

    // Set identifier values
    this.id.categoryId = category.getId();
    this.id.itemId = item.getId();

    // Guarantee referential integrity
    category.getCategorizedItems().add(this);
    item.getCategorizedItems().add(this);
}

它接受类别和项目对象。如果我创建一个Category和一个Item并希望用这种技术连接它们,那么它们显然必须保持BEFORE,因为category.getId()和item.getId()返回null。

是否有“Hibernate包中的技巧”可以级联保存连接表?连接表有其他列。我想在我的网页控制器中保存onSuccess处理程序中的所有三个对象。必须插入所有三个实体或不插入任何实体。

1 个答案:

答案 0 :(得分:2)

你说

  

我的目标是在一次交易中保存Item,Category和CategorizedItem

Hibernate包中是否有可以级联保存连接表的技巧?

是的,使用MutableInt

@Entity
public class CategorizedItem implements Serializable {

    private CategorizedItemId categorizedItemId;

    private String userName;

    private Category category;
    private Item item;

    /**
      * required no-arg constructor
      */
    public CategorizedItem() {}
    public CategorizedItem(CategorizedItemId categorizedItemId) {
        this.categorizedItemId = categorizedItemId;
    }
    public CategorizedItem(String userName, Category category, Item item) {
        this.userName = userName;

        this.categorizedItemId = new CategorizedItemId(category.getIdAsMutableInt(), item.getIdAsMutableInt());
    }

    @EmbeddedId
    public CategorizedItemId getCategorizedItemId() {
        return this.categorizedItemId;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="CATEGORY_ID", insertable=false, updateable=false)
    public Category getCategory() {
        return this.category;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="ITEM_ID", insertable=false, updateable=false)
    public Item getItem() {
        return this.item;
    }

    // setter's goes here

    /**
      * It MUST implements Serializable
      * It MUST overrides equals and hashCode method
      * It MUST has a no-arg constructor
      *
      * Hibernate/JPA 1.0 does not support automatic generation of compound primary key
      * You SHOULD set up manually
      */
    @Embeddable
    public static class CategorizedItemId implements Serializable {

        private MutableInt categoryId = new MutableInt(-1);
        private MutableInt itemId = new MutableInt(-1);

        /**
          * required no-arg constructor
          */
        public CategorizedItemId() {}
        public CategorizedItemId(MutableInt categoryId, MutableInt itemId) {
            this.categoryId = categoryId;
            this.itemId = itemId;
        }

        @Column(name="CATEGORY_ID", updateable=false, nullable=false)
        public Integer getCategoryId() {
            return this.categoryId.intValue();
        }

        public void setCategoryId(Integer categoryId) {
            return this.categoryId.setValue(categoryId);
        }

        @Column(name="ITEM_ID", updateable=false, nullable=false)
        public Integer getItemId() {
            return this.itemId.intValue();
        }

        public void setItemId(Integer itemId) {
            return this.itemId.setValue(itemId);
        }

        // getter's and setter's

        @Override
        public boolean equals(Object o) {
            if(!(o instanceof CategorizedItemId))
                return null;

            finalCategorizedItemId other = (CategorizedItemId) o;
            return new EqualsBuilder().append(getCategoryId(), other.getCategoryId())
                                      .append(getItemId(), other.getItemId())
                                      .isEquals();
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder().append(getCategoryId())
                                        .append(getItemId())
                                        .toHashCode();  
        }

    }

}

这里是分类

@Entity
public class Category implements Serializable {

    public MutableInt id = new MutableInt(-1);

    private List<CategorizedItem> categorizedItemList = new ArrayList<CategorizedItem>();

    @Transient
    public MutableInt getIdAsMutableInt() {
        return this.id;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return this.id.intValue();
    }

    public void setId(Integer id) {
        return this.id.setValue(id);
    }

    @OneToMany(mappedBy="category")
    @JoinColumn(name="CATEGORY_ID", insertable=false, updateable=false)
    @Cascade(CascadeType.SAVE_UPDATE)
    public List<CategorizedItem> getCategorizedItemList() {
        return categorizedItemList;
    }

    // setter's

    /**
      * Use this method when you have a saved Item
      */
    public void addCategorizedItem(CategorizedItem categorizedItem) {
        categorizedItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(), categorizedItem.getItem().getIdAsMutableInt()));
        categorizedItem.setCategory(this);

        getCategorizedItemList().add(categorizedItem);
    }

}

和物品

@Entity
public class Item implements Serializable {

    public MutableInt id = new MutableInt(-1);

    private List<CategorizedItem> categorizedItemList = new ArrayList<CategorizedItem>();

    @Transient
    public MutableInt getIdAsMutableInt() {
        return this.id;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return this.id.intValue();
    }

    public void setId(Integer id) {
        return this.id.setValue(id);
    }

    @OneToMany(mappedBy="item")
    @JoinColumn(name="ITEM_ID", insertable=false, updateable=false)
    @Cascade(CascadeType.SAVE_UPDATE)
    public List<CategorizedItem> getCategorizedItemList() {
        return this.categorizedItemList;
    }

    // setter's

    /**
      * Use this method when you have a saved Category
      */
    public void addCategorizedItem(CategorizedItem categorizedItem) {
        categorizedItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(), categorizedItem.getCategory().getIdAsMutableInt()));
        categorizedItem.setItem(this);

        getCategorizedItemList().add(categorizedItem);
    }

}

现在因为在保存CategorizedItem之前需要categoryId和itemId ,请执行以下操作

Category category = new new Category();
Item item = new Item();

session.save(new Category());
session.save(new Item());
session.save(new CategorizedItem(userName, category, item));

请注意,当您拥有已保存的类别或已保存的项目时,级联才有效。否则,您需要按照上面显示的方法