Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将@OneToMany实体与子实体一起保存(@EmbeddedId与复合外键)_Java_Hibernate_Jpa - Fatal编程技术网

Java 将@OneToMany实体与子实体一起保存(@EmbeddedId与复合外键)

Java 将@OneToMany实体与子实体一起保存(@EmbeddedId与复合外键),java,hibernate,jpa,Java,Hibernate,Jpa,我有这些桌子: CREATE TABLE company ( id VARCHAR(256) NOT NULL, tenantId VARCHAR(256) NOT NULL, fieldName VARCHAR(256) NOT NULL, PRIMARY KEY (id, tenantId, fieldName) ); CREATE TABLE employee ( tenantId VARCHAR(256) NOT NULL, compan

我有这些桌子:

CREATE TABLE company (
    id VARCHAR(256) NOT NULL,
    tenantId VARCHAR(256) NOT NULL,
    fieldName VARCHAR(256) NOT NULL,
    PRIMARY KEY (id, tenantId, fieldName)
);

CREATE TABLE employee (
    tenantId VARCHAR(256) NOT NULL,
    companyFieldName VARCHAR(256) NOT NULL,
    companyId VARCHAR(256) NOT NULL,
    fieldName VARCHAR(256) NOT NULL,
    PRIMARY KEY (tenantId, companyFieldName, companyId, fieldName),
    CONSTRAINT fkCompany FOREIGN KEY (tenantId, companyFieldName, companyId) REFERENCES employee (tenantId, fieldName, id)
);
  • 一个公司可以有很多员工
  • 公司的主键是由3个字段组成的复合键
  • 员工的主键由公司的复合键(即外键)和公司特有的另一个字段组成
基于这一相关问题:

我创建了以下实体:

@Embeddable
public class CompanyIdentity implements Serializable
{
    @NotBlank
    private String tenantId;

    @NotBlank
    private String fieldName;

    @NotBlank
    private String id;

    //getters, setters, equals and hashcode ommited
}

@Entity
public class Company implements Serializable
{
    @EmbeddedId
    private CompanyIdentity companyIdentity;

    @OneToMany(mappedBy = "company")
    private Set<Employee> employees;

    //getters, setters, equals and hashcode ommited
}

@Embeddable
public class EmployeeIdentity implements Serializable
{
    @NotNull
    private CompanyIdentity companyIdentity;

    // This *not* the fieldName in the CompanyIdentity, this is a property
    // specific to an employee, it just happens to have the same name
    @NotBlank
    private String fieldName; 

    //getters, setters, equals and hashcode ommited
}

public class Employee implements Serializable
{
    @EmbeddedId
    private EmployeeIdentity employeeIdentity;

    @MapsId("companyIdentity")
    @JoinColumns({
        @JoinColumn(name = "tenantId", referencedColumnName = "tenantId"),
        @JoinColumn(name = "companyFieldName", referencedColumnName = "fieldName"),
        @JoinColumn(name = "companyId", referencedColumnName = "id")
    })
    @ManyToOne
    @Cascade(value={org.hibernate.annotations.CascadeType.ALL})
    private Company company;

    //getters, setters, equals and hashcode ommited
}
@可嵌入
公共类CompanyIdentity实现了可序列化
{
@不空白
私人字符串租户;
@不空白
私有字符串字段名;
@不空白
私有字符串id;
//getter、setter、equals和hashcode均已指定
}
@实体
公共类公司实现可序列化
{
@嵌入ID
私人公司身份公司身份;
@OneToMany(mappedBy=“公司”)
私人雇员;
//getter、setter、equals和hashcode均已指定
}
@可嵌入
公共类EmployeeIdentity实现可序列化
{
@NotNull
私人公司身份公司身份;
//这*不是*公司身份中的字段名,这是一个属性
//具体到一个员工,它只是碰巧有相同的名字
@不空白
私有字符串字段名;
//getter、setter、equals和hashcode均已指定
}
公共类Employee实现了可序列化
{
@嵌入ID
私人雇员身份雇员身份;
@MapsId(“公司身份”)
@连接柱({
@JoinColumn(name=“tenantId”,referencedColumnName=“tenantId”),
@JoinColumn(name=“companyFieldName”,referencedColumnName=“fieldName”),
@JoinColumn(name=“companyId”,referencedColumnName=“id”)
})
@许多酮
@级联(值={org.hibernate.annotations.CascadeType.ALL})
私营公司;
//getter、setter、equals和hashcode均已指定
}
我想拯救一家只有一名员工的公司,让它写一份报告 行到公司表和员工表,但每当我运行 接下来,我只看到一行写入公司表 而不是员工表

我不确定下面的方法是否正确,或者可能是实体 以上是不正确的吗

public interface CompanyRepository extends CrudRepository<Company, String> {}
public interface CompanyRepository扩展了crudepository{}
最终公司=新公司();
最终公司身份公司身份=新公司身份(“公司租户id”、“公司字段名”、“公司id”);
公司。设置公司身份(公司身份);
最终员工=新员工();
最终雇员身份EmployeeIdentity=新雇员身份();
employeeIdentity.setFieldName(“员工字段名”);
员工身份。设置公司身份(公司身份);
employee.setEmployeeIdentity(employeeIdentity);
员工。设置公司(公司);
final Set employees=new HashSet();
employees.add(employees);
公司员工(员工);
公司保存。保存(公司)//只救公司,不救员工?

非常感谢

您正在使用公司存储库保存公司,但公司没有级联注释

@OneToMany(mappedBy = "company")
private Set<Employee> employees;
@OneToMany(mappedBy=“company”)
私人雇员;
应该是:

@OneToMany(mappedBy = "company")
@Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Set<Employee> employees;
@OneToMany(mappedBy=“company”)
@级联(值={org.hibernate.annotations.CascadeType.ALL})
私人雇员;

谢谢@Klaas,看起来不错。但当我试图用不同的租户(或不同的字段名/id)保存第二个公司+员工时,我遇到了一个约束冲突:
唯一索引或主键冲突:\“FKCOMPANYFIELDNAME\u index\u 1 ON PUBLIC.company(fieldName)值('a-company-field-name',1)\”;SQL语句:\n插入公司
。有什么想法吗?在Employee表中,四个字段的组合:tenantId+companyFieldName+companyId+fieldName应该作为主键,因此我应该能够通过更改其中一个字段来添加另一个company+Employee。在这种情况下,Employee类中外键的设置不起作用。中的示例2可以用于您的案例。谢谢,实际上这是我的外键是如何定义的。在我最初的问题中,我已经更新了它,看起来更好了。
@OneToMany(mappedBy = "company")
@Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Set<Employee> employees;