【发布时间】:2018-03-21 13:07:40
【问题描述】:
我有一个实体的版本控制作为其主键的一部分。版本控制是通过上次修改的时间戳完成的:
@Entity
@Table(name = "USERS")
@IdClass(CompositeKey.class)
public class User {
@Column(nullable = false)
private String name;
@Id
@Column(name = "ID", nullable = false)
private UUID id;
@Id
@Column(name = "LAST_MODIFIED", nullable = false)
private LocalDateTime lastModified;
// Constructors, Getters, Setters, ...
}
/**
* This class is needed for using the composite key.
*/
public class CompositeKey {
private UUID id;
private LocalDateTime lastModified;
}
UUID 会自动转换为数据库的String 并返回模型。 LocalDateTime 也是如此。它会自动转换为 Timestamp 并返回。
我的应用程序的一个关键要求是:数据可能永远不会更新或删除,因此任何更新都将导致新条目具有更年轻的lastModified。满足上述要求代码并在此之前工作正常。
现在是有问题的部分:我想要另一个对象在用户上引用。由于版本控制,这将包括 lastModified 字段,因为它是主键的一部分。这会产生一个问题,因为引用可能很快就过时了。
方法可能取决于User 的id。但是如果我尝试这个,JPA 会告诉我,我喜欢访问一个不是 Entity 的字段:
@Entity
@Table(name = "USER_DETAILS")
public class UserDetail {
@Id
@Column(nullable = false)
private UUID id;
@OneToOne(optional = false)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private UUID userId;
@Column(nullable = false)
private boolean married;
// Constructors, Getter, Setter, ...
}
解决我的困境的正确方法是什么?
编辑
我收到了JimmyB 的建议,我也尝试过但也失败了。我在这里添加了失败的代码:
@Entity
@Table(name = "USER_DETAILS")
public class UserDetail {
@Id
@Column(nullable = false)
private UUID id;
@OneToMany
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private List<User> users;
@Column(nullable = false)
private boolean married;
public User getUser() {
return users.stream().reduce((a, b) -> {
if (a.getLastModified().isAfter(b.getLastModified())) {
return a;
}
return b;
}).orElseThrow(() -> new IllegalStateException("User detail is detached from a User."));
}
// Constructors, Getter, Setter, ...
}
【问题讨论】:
-
“但是如果我尝试这个,JPA 会告诉我,我喜欢访问一个不是实体的字段。” - 您在这里如何/尝试了什么?
-
依赖
User的id。我用代码示例更新了我的问题。 -
为什么f...你在主键中包含版本????
-
正如我在要求中所说:数据可能永远不会改变,因此只允许插入。
-
@Gab 因为否则他需要添加另一个人工密钥。
标签: java oracle jpa eclipselink or-mapper