Java Hibernate:仅将manyTone映射到具有特定列值的外键实体

Java Hibernate:仅将manyTone映射到具有特定列值的外键实体,java,hibernate,hibernate-mapping,Java,Hibernate,Hibernate Mapping,我觉得这有点奇怪,我不确定这是否可能,但我的要求如下: @Entity @Table(name = "organization") public class Organization { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String type; private String name; pr

我觉得这有点奇怪,我不确定这是否可能,但我的要求如下:

@Entity
@Table(name = "organization")
public class Organization {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;    
    private String type;
    private String name;
    private String address;
    private String status;
    private String subtype;
    
    @Column(name = "created_date")
    @Temporal(value =  TemporalType.TIMESTAMP)
    private Date createdDate;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "organization_id", insertable = false, updatable = false)
    private List<User> users;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({ @JoinColumn(name = "subtype", referencedColumnName = "name", insertable = false, updatable = false),
            @JoinColumn(name = "type", referencedColumnName = "organization_type", insertable = false, updatable = false) })
    private OrganizationSubType organizationSubType;

    // Getters and setters
.
.
.
我有两个实体:
数据集
组织
数据集
实体具有到
组织
实体的多对一映射。组织有两种类型:
客户
合作伙伴
。业务需求是只有
合作伙伴
类型的组织才能拥有数据集。那么,有没有办法将
数据集
实体映射到
组织
,使得
数据集
中的所有外键只包含
组织
实体的ID,这些实体属于
合作伙伴

组织实体的定义如下:

@Entity
@Table(name = "organization")
public class Organization {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;    
    private String type;
    private String name;
    private String address;
    private String status;
    private String subtype;
    
    @Column(name = "created_date")
    @Temporal(value =  TemporalType.TIMESTAMP)
    private Date createdDate;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "organization_id", insertable = false, updatable = false)
    private List<User> users;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({ @JoinColumn(name = "subtype", referencedColumnName = "name", insertable = false, updatable = false),
            @JoinColumn(name = "type", referencedColumnName = "organization_type", insertable = false, updatable = false) })
    private OrganizationSubType organizationSubType;

    // Getters and setters
.
.
.

那么,有没有办法在映射上设置一个约束,使新的数据集实体被持久化时,组织id始终属于partner而不是customer类型的实体?或者我必须将客户和合作伙伴组织作为单独的实体分开吗?

有几种方法可以实现这一点:

  • 在持久化之前,在构建新的
    Dataset
    对象时,在业务层的位置添加验证。这种验证将检查给定的
    组织
    是否可以与基于组织类型创建的
    数据集
    实体相关联

  • 通过使用Bean验证API&定义自定义约束验证器。这种验证器将由实体上的每个更改调用

  • 将hibernate验证程序添加到类路径

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.3.4.Final</version>
    </dependency>
    
  • 通过使用
    SQL检查约束
    if您使用的数据库支持它-就像中的示例一样

  • 通过将合作伙伴组织和客户组织建模为单独的实体类


  • 因为合作伙伴和客户的组织结构与方案4中的方法相同。看起来情况太复杂了。我建议您选择选项1。

    谢谢您提供了可能的解决方案。我已经在考虑在我的服务层中实现一些自定义逻辑。我只是想看看是否可以在Hibernate本身设置一些约束。
    @Constraint(validatedBy = PartnerOrganisationValidator.class)
    @Target(FIELD)
    @Retention(RUNTIME)
    @Documented
    public @interface PartnerOrganisation {
        String message() default "Organisation should be of type PARTNER";
        Class<?>[] groups() default { };
        Class<? extends Payload>[] payload() default { };
    }
    
    public class PartnerOrganisationValidator implements ContraintValidator<PartnerOrganisation, Organisation> {
        @Override
        public boolean isValid(Organisation organisation, ConstraintValidatorContext constraintValidatorContext) {
            return organisation == null || "PARTNER".equals(organisation.type);
        }
    }
    
        @PartnerOrganisation
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name="partner_id", referencedColumnName="id", insertable = false, updatable = false)
        private Organization partner;