Hibernate - 带附加列的链接表 - 保存在一个事务中 [英] Hibernate - link table with additional columns - saving in one transaction

查看:84
本文介绍了Hibernate - 带附加列的链接表 - 保存在一个事务中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Hibernate,并阅读Java Persistence with Hibernate一书中的7.2.3添加列来连接表一章。我的目标是在一次交易中保存商品,类别和CategorItem。



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

  public CategorizedItem(String username,Category category,Item item){
//设置字段
this.username = username;

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

//设置标识符值
this.id.categoryId = category.getId();
this.id.itemId = item.getId();

//保证参照完整性
category.getCategorItems()。add(this);
item.getCategorizedItems()。add(this);
}

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



Hibernate包中有一个技巧可以级联保存连接表吗?连接表具有附加列。我想将所有三个对象保存在我的网页控制器的onSuccess处理程序中。

解决方案

您说过,


我的目标是将商品,类别和CategorItem 保存在一个交易中





是的,使用MutableInt


$ b在Hibernate包中有一个技巧可以级联保存连接表吗? $ b

  @Entity 
public class CategorItem implements Serializable {

private CategorizedItemId categorItemId;

private String userName;

私人类别类别;
私人商品项目;
$ b $ **
*要求无参数构造函数
* /
public CategorizedItem(){}
public CategorizedItem(CategorizedItemId categorItemId){
this.categorizedItemId = categorItemId;
}
public CategorizedItem(String userName,Category category,Item item){
this.userName = userName;

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

@EmbeddedId
public CategorizedItemId getCategorItemId(){
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去这里

/ **
*它必须实现Serializable
*它必须覆盖equals和hashCode方法
*它必须有一个无参数构造函数
*
* Hibernate / JPA 1.0不支持自动生成复合主键
*您应该手动设置
* /
@Embeddable
public static class CategorizedItemId implements Serializable {

private MutableInt categoryId = new MutableInt(-1);
private MutableInt itemId = new MutableInt(-1);
$ b / **
*所需的无参数构造函数
* /
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和setter的

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

finalCategorizedItemId other =(CategorizedItemId)o;
返回新的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);

私人清单< CategorizedItem> categorItemList = new ArrayList< CategorItem>();

@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);
$
$ b @OneToMany(mappedBy =category)
@JoinColumn(name =CATEGORY_ID,insertable = false,updateable = false)
@Cascade( CascadeType.SAVE_UPDATE)
public List< CategorizedItem> getCategorItemList(){
return categorizedItemList;
}

// setter's

/ **
*当您有保存的项目
* / $ b $时使用此方法b public void addCategorizedItem(CategorizedItem categorItem){
categorItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(),categorItem.getItem()。getIdAsMutableInt()));
categorItem.setCategory(this);

getCategorItemList()。add(categorItem);
}

}

和项目

  @Entity 
public class Item实现Serializable {

public MutableInt id = new MutableInt(-1);

私人清单< CategorizedItem> categorItemList = new ArrayList< CategorItem>();

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

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

// setter's

/ **
*当您保存的类别
* / $ b $时使用此方法b public void addCategorItem(CategorizedItem categorItem){
categorItem.setCategorizedItemId(new CategorizedItemId(getIdAsMutableInt(),categorItem.getCategory()。getIdAsMutableInt()));
categorItem.setItem(this);

getCategorItemList()。add(categorItem);
}

}

现在因为 categoryId和itemId 之前保存CategorItem,如下所示:

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

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

请注意,当您有保存的类别或保存的项目时,级联正常工作。否则,您需要按照上面显示的方法

I am learning Hibernate and just read the chapter "7.2.3 Adding columns to join tables" of the "Java Persistance with Hibernate" book. My goal is to save Item, Category and CategorizedItem in one transaction.

There is a constructor there (page 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);
}

It accepts category and item objects. If I create a Category and an Item and want to connect them with this technique, they obviously have to be persisted BEFORE, as category.getId() and item.getId() return null.

Is there "a trick in the Hibernate bag" that can cascade the saving of a join table? The join table have additional columns. I want to save all three objects in the onSuccess handler in my web page controller. All three entities or none of them must be inserted.

解决方案

You said

My goal is to save Item, Category and CategorizedItem in one transaction

Is there a trick in the Hibernate bag that can cascade the saving of a join table ?

Yes, use 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();  
        }

    }

}

Here goes Category

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

}

And Item

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

}

Now because you need categoryId and itemId before saving CategorizedItem, do as follows

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

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

Notice the cascading just works when you have either a saved Category or a saved Item. Otherwise, you need to follow the approach shown above

这篇关于Hibernate - 带附加列的链接表 - 保存在一个事务中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆