如何使用 Hibernate 在内部保存带有集合的实体?
Posted
技术标签:
【中文标题】如何使用 Hibernate 在内部保存带有集合的实体?【英文标题】:How to persist entity with collection inside by using Hibernate? 【发布时间】:2014-04-13 11:44:15 【问题描述】:我正在尝试使用 Hibernate ORM 在我的数据库中保留一个实体。我的entity class
@Entity
@Table(name = "company")
public class Company implements Serializable
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column
private String name;
@OneToMany(mappedBy = "company")
@LazyCollection(LazyCollectionOption.FALSE)
private Collection<Employee> employees;
存储库
@Repository
@Transactional(propagation = Propagation.REQUIRED)
public class HibernateCompanyRepository implements CompanyRepository
@Autowired
HibernateTemplate template;
@Override
public Company getCompany(int id)
return template.get(Company.class, id);
@Override
public Collection<Company> getCompanies()
return template.loadAll(Company.class);
@Override
public void addCompany(Company employee)
template.save(employee);
@Override
public void deleteCompany(int id)
template.delete(template.get(Company.class, id));
@Override
public void updateCompany(Company company)
template.update(company);
这是我的控制器
@Controller
@RequestMapping("/company")
public class CompanyController
@Autowired
CompanyRepository companyRepository;
@RequestMapping(value = "/id",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody public Company getCompany(@PathVariable("id") Integer id)
return companyRepository.getCompany(id);
@RequestMapping(method = RequestMethod.PUT,
consumes = "application/json",
headers = "content-type=application/json")
public String updateCompany(@RequestBody Company company)
companyRepository.updateCompany(company);
return "redirect:/company/" + company.getId();
// another methods ommited
旧的 JSON
"name" : "IBM",
"employees" : [
"name" : "John",
"id" : 2
,
"name" : "Bill",
"id" : 4
],
"id" : 2
更新的 JSON(Bill 已删除)
"name" : "IBM",
"employees" : [
"name" : "John",
"id" : 2
],
"id" : 2
我在updateCompany()
方法中收到一个Employee 实体。 Entity
已成功更新。它改变了员工的集合(例如我删除了一名员工)。但是 Hibernate 不能持久化这个更新的实体。当我试图检索它时,我发现没有发生任何变化。有什么建议可以解决吗?
更新:
我正在尝试先更新已删除的员工
@Override
public void updateCompany(Company company)
Company oldCompany = getCompany(company.getId());
for (Employee employee : oldCompany.getEmployees())
if (!company.getEmployees().contains(employee))
employee.setCompany(null);
template.update(employee);
template.update(company);
得到异常
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [eu.flavio.restful.entity.Company#2]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [eu.flavio..restful.entity.Company#2]
【问题讨论】:
【参考方案1】:对 Hibernate 来说重要的是双向关联的所有者。所有者方是没有mappedBy
属性的一方。这就是它寻找是否存在关联网络实体的地方。
这里的所有者是Employee.company
。 Company.employees
是反面。如果您希望 Bill 不再是 IBM 的一部分,则必须确保将 Bill 的公司设置为 null。
【讨论】:
以上是关于如何使用 Hibernate 在内部保存带有集合的实体?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA 是不是在内部使用 Hibernate 以及如果我不提供方言属性,为啥我的应用程序正在运行?