如何使用 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.companyCompany.employees 是反面。如果您希望 Bill 不再是 IBM 的一部分,则必须确保将 Bill 的公司设置为 null。

【讨论】:

以上是关于如何使用 Hibernate 在内部保存带有集合的实体?的主要内容,如果未能解决你的问题,请参考以下文章

保存在内部存储中捕获的​​图片?

如何从 cordova 应用程序将文件保存在内部存储中?

如何在内部保存我的数据?

如何在内部保存数据?

如何在内部存储中创建文件夹并保存捕获的图像

Spring Data JPA 是不是在内部使用 Hibernate 以及如果我不提供方言属性,为啥我的应用程序正在运行?