简体   繁体   English

如何使用Hibernate在集合内部持久化实体?

[英]How to persist entity with collection inside by using Hibernate?

I'm trying to persist an entity in my DB using Hibernate ORM . 我正在尝试使用Hibernate ORM将实体保留在数据库中。 My entity class 我的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 资料库

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

Here is my controller 这是我的控制器

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

Old JSON 旧的JSON

{
  "name" : "IBM",
  "employees" : [
    {
      "name" : "John",
      "id" : 2
    },
    {
      "name" : "Bill",
      "id" : 4
    }
  ],
  "id" : 2
}

Updated JSON (Bill was deleted) 更新了JSON(清单已删除)

{
  "name" : "IBM",
  "employees" : [
    {
      "name" : "John",
      "id" : 2
    }
  ],
  "id" : 2
}

I receive an Employee entity in my updateCompany() method. 我在updateCompany()方法中收到一个Employee实体。 Entity has been succesfully updated. Entity已成功更新。 It has changed collection of Employee (for example I removed one employee). 它更改了Employee的集合(例如,我删除了一名雇员)。 But Hibernate can't persist this updated entity. 但是Hibernate无法持久存储此更新的实体。 When I'm trying to retrieve it I see no changes happend. 当我尝试检索它时,我看不到任何变化。 Any suggestions how to fix it? 有什么建议如何解决吗?

UPD: UPD:

I'm trying to update my deleted employees first 我正在尝试先更新已删除的员工

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

And get exception 并获得例外

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]

What matters to Hibernate is the owner side of the bidirectional association. Hibernate重要的是双向关联的所有者。 The owner side is the side which does NOT have the mappedBy attribute. 所有者端是不具有mappedBy属性的端。 That's where it looks to find if an association netween entities exist of not. 这就是寻找实体之间是否存在不存在关联的地方。

The owner side here is thus Employee.company . 因此,此处的所有者是Employee.company Company.employees is the inverse side. Company.employees是相反的一面。 You must make sure that Bill's company is set to null if you want Bill not to be part of IBM anymore. 如果您希望Bill不再是IBM的一部分,则必须确保Bill的公司设置为null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM