繁体   English   中英

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

[英]Hibernate: Join table with extra columns, remove children from one side

场景如下

我有2个表,公司和活动。 公司可以有一个或多个活动。 其中一项活动是“主要”活动,所有其他活动都是次要活动。

为了解决这个问题,我为连接表创建了2个实体(Activity,Company)和第三个实体,即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<>();
}

Activity.java

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

CompanyActivity.java

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

}

为公司添加活动没有问题。 子集合包含新添加的活动,并且始终有一个标记为主要的预期。

更新公司时会出现问题。

  • 当我添加新活动时,所有先前的现有活动将再次保留。
  • 当我删除活动时,它不会从表中删除。

我正在使用此代码更新公司的活动

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

    company = repository.save(company);

在此代码中, newActivities具有应该考虑的新活动(此集合没有以前的那些,我只是将它们全部替换)

我尝试将orphanRemoval=true添加到公司的@OneToMany(cascade = CascadeType.ALL, mappedBy = "company") ,但是当没有其他公司正在使用它时,这会删除活动类型,这是错误的,因为它们应始终可用。

能否帮助我同步Companyactivities集合而不从Activity表中删除元素?

非常感谢!

我解决了 以下是我遵循的步骤。

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

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

}

然后,我再次将“orphanRemoval”属性添加到公司映射,并更改了我的CascadeTypes,如下所示

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

通过这些更改,我的映射按预期工作,使用与替换关系相同的代码。

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

company = repository.save(company);

谢谢 :)

您创建实体的方式不正确。 您无需为连接表创建实体(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<>();

有关如何使用Join表的一对多/多对一的更详细说明: http//www.codejava.net/frameworks/hibernate/hibernate-one-to-many-association-on-join -table-注解-示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM