Java Hibernate:使用额外的列连接表,从一侧删除子项
场景如下 我有两张桌子,公司和活动。一个公司可以有一个或多个活动。其中一项活动是“主要”活动,而所有其他活动都是次要的 为了处理这个问题,我为联接表创建了两个实体(活动、公司)和第三个实体,即CompanyActivity 我用它作为起点 在我的代码下面(省略了getter和setter) Company.javaJava 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_
@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',它确定哪个是公司的主要活动。用你描述的方法,我做不到。