如何将多个ManyToOne注释到同一个实体,但其中一个字段必须相同

时间:2017-10-03 06:43:13

标签: java hibernate jpa

我有以下两个实体:

@Entity
@Table(name="user")
public class User {
    @Id
    @Column("id")
    private long id;

    @Column(name="code", nullable = false)
    private String code;

    @Column(name="session_id", nullable = false)
    private long sessionId;
}

@Entity
@Table(name="task")
public class Task {
    @Id
    @Column("id", nullable = false)
    private long id;

    @ManyToOne(optional = false)
    @JoinColumn(name="primary_user_code", referencedColumnName = "code", nullable = "false")
    private User primaryUser;

    @ManyToOne(optional = true)
    @JoinColumn(name="secondary_user_code", referencedColumnName = "code", nullable = "true")
    private User secondaryUser;
}

问题是User中的两个Task对象必须具有相同的sessionId。有没有办法使用hibernate注释强制执行此操作?或者我只是咬紧牙关并在代码中强制执行它?

我尝试查看@Where@WhereJoinTable注释,但根据此hibernate错误报告link@ManyToOne不支持

更新

我应该提到User已经存在且无法更改。我控制的是我要添加的Task类。

代码不是唯一的,它与session_id一起标识一个唯一的用户。 session_id引用单独的表,但未使用@OneToOne关系进行注释。它只是一个普通列,与Session表的关系在代码中处理。基本上每个User都有一个代码,并链接到多个Sessions,其中只有一个可以是活动的。

对于我要添加的任务表,我想要注释如果可能

2 个答案:

答案 0 :(得分:0)

这在经典SQL中是不可能的。每行应用检查约束,并且由于两个session_ids出现在两个不同的行中,因此检查约束将无济于事。在Oracle中,您可以快速提交刷新MV,并对此类情况进行约束,但这不在此范围内。

最好的办法是使用@PrePersist @PreUpdate回调来检查Java端的这种情况。

ClientCredentials clientCreds = new ClientCredentials();
clientCreds.Windows.ClientCredential.UserName = "username";
clientCreds.Windows.ClientCredential.Password = "pass";
clientCreds.Windows.ClientCredential.Domain = "domain";
IServiceConfiguration<IOrganizationService> orgConfigInfo = ServiceConfigurationFactory.CreateConfiguration<IOrganizationService>(new Uri("http://yourcrmserver/CRO/XRMServices/2011/Organization.svc"));
OrganizationServiceProxy orgserv = new OrganizationServiceProxy(orgConfigInfo, clientCreds);

当然,棘手的部分是正确处理异常。 entityManager将事务标记为回滚。因此,如果业务逻辑中的检查失败,这应该是您的最后一道防线。

答案 1 :(得分:0)

您可以编写自定义验证注释和实现ConstraintValidator的类。通过覆盖其isValid方法,您可以将自定义逻辑添加到自定义注释中。查看this示例。