2016-09-30 62 views
0

我遇到了标题中描述的问题,保存我的实体,尽管代码和数据库表中的所有内容都可以。
这里是我的代码:休眠/ JPA,字段'accreditation_company_id'没有默认值错误

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

这里是我的表定义:

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 

对象我试图保存包含以下信息:

公司(ID = 32,companyObjects = [CompanyObject(id = null,type = NEW)])

下面是我用来保存对象的代码:

控制器的方法:

@RequestMapping(value = "/company/{id}", method = RequestMethod.POST) 
public String editCompany(@PathVariable("id") long companyId, 
          @ModelAttribute("form") CompanyDto form) { 
    Company company = companyService.getCompanyById(companyId); 
    companyService.updateCompany(company, form); 
    return "redirect:/companies"; 
} 

服务方法:

@Transactional 
    public Company updateCompany(Company company, final CompanyDto form) { 
     company.getCompanyObjects().clear(); 
     company.getCompanyObjects().addAll(form.getCompanyObjects()); 
     return companyRepository.save(company); 
    } 

我会收到这个正确的,自动休眠生成并填充这些对象的所有丢失的IDS?如果是,我错过了什么,为什么错误出现?

+0

你是如何保存这些对象的?向我们展示一些代码。 – nagyf

+0

@nagyf,我用一些代码更新答案。感谢评论! –

回答

1

这里有一些问题。首先,你的表定义是错误的,检查你的accreditation_object表,你有一个外键引用一个不存在的列:company_id应该是accreditation_company_id。 (或只是一些复制粘贴错误?)

其次,你的实体是错误的,试试这个方法:

@Entity 
public class Company { 

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

    @OneToMany(mappedBy="company", cascade = CascadeType.ALL) 
    Set<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; 
} 

注意@ManyToOne标注在CompanyObject。如果我理解正确,您想要将一个或多个CompanyObject分配给公司,因此您必须在CompanyObject中有@ManyToOne注释Company类型的字段。

现在,如果你想保存这些对象,先救Company实例,然后遍历的CompanyObject是清单中,将以前保存的公司实例,然后保存CompanyObject S,这样的事情:

Company company = new Company(); 
companyDao.persist(company); 

List<CompanyObject> companyObjects = new ArrayList<>(); 
// populate the list somehow 
// ... 

for(CompanyObject obj: companyObjects){ 
    obj.setCompany(company); 
    companyObjectDao.persist(obj); 
} 

你的updateCompany方法是错误的,你应该尝试类似上面的代码。 (我无法重写的例子,因为它看起来像缺了点什么有什么是CompanyDTO?)

编辑:可以使用级联节能(注:我已经更新了Company实体),只是一定要设置在Company实例每CompanyObject实例,如:

@Transactional 
public Company updateCompany(Company company, final CompanyDto form) { 
    company.getCompanyObjects().clear(); 
    company.getCompanyObjects().addAll(form.getCompanyObjects()); 
    for(CompanyObject obj : company.getCompanyObjects()){ 
     obj.setCompany(company); 
    } 
    return companyRepository.save(company); 
} 

我认为这应该工作,但我不是100%肯定。试一试。

+0

感谢万@nagyf,我会试试看。关于命名的混乱 - 你说得对,这只是一个复制粘贴的错误。只是想知道是否有可能离开对象结构,并以某种方式进行保存?是不是'cascade'属性是为孩子保存而设计的,是吗? –

+0

我已更新答案 – nagyf

+0

谢谢,@nagyf,它的工作原理,你是一个拯救生命的人! –

相关问题