Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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 Hibernate:使用额外的列连接表,从一侧删除子项_Java_Mysql_Hibernate_Spring Data - Fatal编程技术网

Java Hibernate:使用额外的列连接表,从一侧删除子项

Java Hibernate:使用额外的列连接表,从一侧删除子项,java,mysql,hibernate,spring-data,Java,Mysql,Hibernate,Spring Data,场景如下 我有两张桌子,公司和活动。一个公司可以有一个或多个活动。其中一项活动是“主要”活动,而所有其他活动都是次要的 为了处理这个问题,我为联接表创建了两个实体(活动、公司)和第三个实体,即CompanyActivity 我用它作为起点 在我的代码下面(省略了getter和setter) Company.java @Entity @Table(name = "T_COMPANY") public class Company { @Id @Column(name = "COM_

场景如下

我有两张桌子,公司和活动。一个公司可以有一个或多个活动。其中一项活动是“主要”活动,而所有其他活动都是次要的

为了处理这个问题,我为联接表创建了两个实体(活动、公司)和第三个实体,即CompanyActivity

我用它作为起点

在我的代码下面(省略了getter和setter)

Company.java

@Entity
@Table(name = "T_COMPANY")
public class Company {

    @Id
    @Column(name = "COM_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company")
    private List<CompanyActivity> activities = new ArrayList<>();
}
@Entity
@Table(name = "T_ACTIVITY")
public class Activity {

    @Id
    @Column(name = "ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String code;

    private String description;

    private boolean availableOnline;
}
@Entity
@Table(name = "T_COMPANY_ACTIVITY")
public class CompanyActivity {

    @Id
    @Column(name = "COM_ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "COM_ID")
    private Company company;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ACT_ID")
    private Activity activity;

    private boolean primary;

}
CompanyActivity.java

@Entity
@Table(name = "T_COMPANY")
public class Company {

    @Id
    @Column(name = "COM_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company")
    private List<CompanyActivity> activities = new ArrayList<>();
}
@Entity
@Table(name = "T_ACTIVITY")
public class Activity {

    @Id
    @Column(name = "ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String code;

    private String description;

    private boolean availableOnline;
}
@Entity
@Table(name = "T_COMPANY_ACTIVITY")
public class CompanyActivity {

    @Id
    @Column(name = "COM_ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "COM_ID")
    private Company company;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ACT_ID")
    private Activity activity;

    private boolean primary;

}
为公司添加活动没有问题。children集合包含新添加的活动,总有一个活动按预期标记为primary

更新公司时会出现问题

  • 当我添加一个新的活动时,所有以前存在的活动都会再次持久化
  • 删除活动时,它不会从表中删除
我正在使用此代码更新公司的活动

    company.getActivities().clear();
    company.getActivities().addAll(newActivities);

    company = repository.save(company);
在此代码中,
newActivities
具有应考虑的新活动(此集合没有以前的活动,我只是将它们全部替换)

我尝试在公司上的
@OneToMany(cascade=CascadeType.ALL,mappedBy=“company”)
中添加
orphaneremovation=true
,但这会在没有其他公司使用活动类型时删除它,这是错误的,因为它们应该总是可用的

您能否帮助我同步
公司
上的
活动
集合,而不删除
活动
表中的元素


非常感谢

您创建实体的方式不正确。您不需要为联接表(CompanyActivity/t_COMPANY_ACTIVITY)创建实体。相反,您应该在活动实体上使用@JoinTable。如下所示:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "company")
@JoinTable(
    name = "T_COMPANY_ACTIVITY",
    joinColumns = @JoinColumn(name = "COM_ID"),
    inverseJoinColumns = @JoinColumn(name = "ACT_ID")
)
private List<CompanyActivity> activities = new ArrayList<>();
@OneToMany(cascade=CascadeType.ALL,mappedBy=“company”)
@可接合(
name=“T_公司_活动”,
joinColumns=@JoinColumn(name=“COM_ID”),
inverseJoinColumns=@JoinColumn(name=“ACT\u ID”)
)
私有列表活动=新建ArrayList();

有关一对多/多对一与联接表如何工作的详细说明,请参见此处:

我解决了这个问题。以下是我遵循的步骤

首先,我更改了联接表实体级联类型,如下所示

@Entity
@Table(name = "T_COMPANY_ACTIVITY")
public class CompanyActivity {

    @Id
    @Column(name = "COM_ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "COM_ID")
    private Company company;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "ACT_ID")
    private Activity activity;

    private boolean primary;

}
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "empresa", orphanRemoval = true)
private List<CompanyActivity> activities = new ArrayList<>();
然后,我再次将“孤儿移除”属性添加到公司映射中,并更改了我的级联类型,如下所示

@Entity
@Table(name = "T_COMPANY_ACTIVITY")
public class CompanyActivity {

    @Id
    @Column(name = "COM_ACT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "COM_ID")
    private Company company;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "ACT_ID")
    private Activity activity;

    private boolean primary;

}
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "empresa", orphanRemoval = true)
private List<CompanyActivity> activities = new ArrayList<>();

谢谢:)

我需要为关系添加一个布尔属性。如果您查看CompanyActivity,我添加了一个布尔值'primary',它确定哪个是公司的主要活动。用你描述的方法,我做不到。