2016-09-30 83 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,它的工作原理,你是一個拯救生命的人! –