Xet*_*ius 1 java mysql spring hibernate
我无法更新实体中包含的集合.我没有收到任何错误,但是当我尝试使用一组不同的升级实体更新产品时,数据库的内容保持不变.
我有一个Product实体,其中包含一组Upgrade实体.
@Entity
@Table(name="product")
public class Product {
private Long id;
private Set<Upgrade> upgrades;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToMany(mappedBy = "products",
targetEntity = Upgrade.class,
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
public Set<Upgrade> getUpgrades() {
return upgrades;
}
public void setUpgrades(Set<Upgrade> upgrades) {
this.upgrades = upgrades;
}
}
@Entity
@Table(name="upgrade")
public class Upgrade {
private Long id;
private Set<Product> products;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToMany(targetEntity = Product.class,
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
@JoinTable(name = "upgrade_product",
joinColumns = @JoinColumn(name = "upgrade_id"),
inverseJoinColumns = @JoinColumn(name="product_id"))
public Set<Product> getProducts() {
return products;
}
public void setProducts(Set<Product> products) {
this.products = products;
}
}
Run Code Online (Sandbox Code Playgroud)
这链接到以下数据库结构:
CREATE TABLE `product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1;
CREATE TABLE `upgrade` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=778 DEFAULT CHARSET=latin1;
CREATE TABLE `upgrade_product` (
`upgrade_id` bigint(20) NOT NULL,
`product_id` bigint(20) NOT NULL,
PRIMARY KEY (`upgrade_id`,`product_id`),
KEY `FK169831CC92B40B3C` (`upgrade_id`),
KEY `FK169831CC6DAEB65C` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)
当我更改Product.upgrades和调用时,sessionFactory.getCurrentSession().update(product)我没有看到这些更改设置.我相信我在这里遗漏了一些东西,但无法弄清楚它是什么.
这是在MySQL 5数据库中.
我正在更新这样的升级集:
List<Upgrade> upgradeList = getSelectedUpgrades(editProduct.getAllUpgrades());
if (compareUpgradeLists(new ArrayList<Upgrade>(product.getUpgrade()), upgradeList) == false) {
product.setUpgrade(new HashSet<Upgrade>(upgradeList));
isDirty = true;
}
if (isDirty) {
productDao.update(product);
}
Run Code Online (Sandbox Code Playgroud)
其中getSelectedUprades是:
private List<Upgrade> getSelectedUpgrades (List<EditProductUpgradeDetails> list) {
List<Upgrade> upgradeList = new ArrayList<Upgrade>();
// Update the upgrades for this product
for (EditProductUpgradeDetails upgradeDetails : list) {
if (upgradeDetails.getSelected()) {
// Add upgrade to new upgrade list
Upgrade upgrade = upgradeDao.get(upgradeDetails.getId());
upgradeList.add(upgrade);
}
}
return upgradeList;
}
Run Code Online (Sandbox Code Playgroud)
并且EditProductUpgradeDetails是一个表单备份对象,其中包含selected链接到该升级的复选框的字段.
我已经使用调试器来检查创建的Set是否不同,并且产品包含了Set,但是,当我在会话上调用升级方法时,它无法将该更改传播到数据库.
从来没有,真的永远不会用新的/其他集合替换Hibernate Managed Collection.你总是必须使用原始集合并使用add和remove方法!
永远不要做这样的事情: product.setUpgrade(new HashSet<Upgrade>(upgradeList));
你需要做点什么
class Product {
...
private Set<Upgrade> upgrades;
...
public void replaceUpgrades(Set<Upgrade> newUpgrades) {
this.upgrades.retainAll(newUpgrades);
HashSet<T> reallyNew = new HashSet<T>(newUpgrades);
reallyNew.removeAll(this.upgrades);
this.upgrades.addAll(reallyNew);
}
Run Code Online (Sandbox Code Playgroud)
}
如果你使用hibernate进行字段注入,那么最好不要在hibernate维护的集合上设置setter.
| 归档时间: |
|
| 查看次数: |
1447 次 |
| 最近记录: |