繁体   English   中英

休眠(Spring JPA)子实体删除

[英]Hibernate (Spring JPA) child entities removal

我正在学习Hibernate(春季),并且面临着从父级实体中删除子实体的奇怪问题。

这是我所拥有的:

父实体:

@Entity  
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "company_id", referencedColumnName = "id")
    List<CompanyObject> companyObjects;
}  

子实体:

@Entity
public class CompanyObject {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @Enumerated(EnumType.STRING)
    ObjectType type;

    @ManyToOne
    @JoinColumn(name = "company_id")
    Company company;
}  

这是我的表定义:

CREATE TABLE `company` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8

CREATE TABLE `company_object` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_id` bigint(20) NOT NULL,
  `type` varchar(50) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK__company` (`company_id`),
  CONSTRAINT `FK__company` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8  

而且,我还有以下update方法:

// some code here
public void update(CompanyDto dto) {
    Company company = repository.getCompanyById(companyId);  
    repository.save(dto.merge(company));
}
// some code here  


public class CompanyDto {
    private List<CompanyObjectDto> companyObjects = new ArrayList<>();

    public Company merge(Company company) {        
        company.getCompanyObjects().clear();
        for (CompanyObjectDto dto : companyObjects) {
            company.getCompanyObjects().add(dto.to(company));
        }
        return company;
    }
}

public class CompanyObjectDto {
    ObjectType type;

    public CompanyObject to(Company company) {
        CompanyObject object = new CompanyObject();
        object.setType(this.getType());
        object.setCompany(company);
        return object;
    }
}

并且,一旦启动update方法,就会出现以下错误: java.sql.SQLWarning: Column 'company_id' cannot be null 我对此进行了一些调查,发现如果我注释掉company.getCompanyObjects().clear(); 字符串可以正常工作,因此将删除动作级联到公司对象似乎存在一些问题。

可以,有人指出我的错误吗? 谢谢。

由于从List中删除对象的对象,然后使用相同的List作为对Company对象的引用,因此出现错误。 参见下面的代码:

private List<CompanyObjectDto> companyObjects = new ArrayList<>(); //Stmt 1

上面的代码用于定义列表,将在您的下面的代码中进行引用:

company.getCompanyObjects().clear(); //It will clear out all objects
    for (CompanyObjectDto dto : companyObjects) { //Iterating over empty list defined in stmt 1.
        company.getCompanyObjects().add(dto.to(company));
    }

因此,您的外键将始终为null,这是不允许的,并且会引发异常。

当您注释掉List#clear行时,您的代码将起作用,因为在这种情况下,列表已经具有一些未修改的引用对象。

您已经双向映射了公司Company和CompanyObject,即两个实体都与另一个实体有关系。

在这种情况下,只能有一个@Joincolumn,并且必须选择一个实体作为拥有实体,而另一个实体则用“ mappedby”标记该关系(请参见http://docs.oracle.com/javaee/6/ api / javax / persistence / ManyToOne.html )。

暂无
暂无

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

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