0

我正在尝试做一些看似简单但我无法弄清楚的事情。我正在使用 JPA2 和休眠,但我想要一个也可以与 EclipseLink 等其他提供商一起使用的解决方案,但这是次要问题。

我有一个凭证表,其中只有一个密码哈希、一个盐和一个用户 ID。我有一个包含一些用户数据的用户表。

以下是我的要求:

  1. 每个用户都必须拥有一个凭证,因此它是一对一的。
  2. 该应用程序只需要创建用户和登录的凭据
  3. 许多其他对象包含用户(即发票、历史记录、地址等),我不希望这些对象在我每次对其进行操作时都间接加载凭据。
  4. 我希望在清理用户时自动清理凭据。

所以这是我的第一次尝试:

@Entity
public class Credential {
    @Id
    private Long id;

    @MapsId
    @OneToOne( optional = false ) // Btw, I don't care if this is lazy loaded or not
    @JoinColumn( name = "user_id" )
    private User user;

    ...

    public Credential( User user, String password ) {
       this.user = user;
       // set salt and hash from password
}

@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;

    @OneToOne( optional=false, mappedBy="user", cascade = CascadeType.ALL, fetch = FetchType.LAZY )
    private Credential credential; // this I do what lazy loaded

    ...

    public void setPassword( String password ) {
        credential = new Credential( this, password );
    }


User user = new User();
user.setName( "Charles Bukowski" );
user.setPassword( "b00z3" );

service.transactedPersist( user );

对此。

好的,所以现在当我坚持用户时,你能猜到会发生什么吗?对,我在插入凭据时遇到数据完整性异常。那是因为,是的,user.id 设置正确,但用户表中还没有行。如果我使凭据 optional=true 它神秘地起作用,但是在持久化之后我似乎在 User 上获得了额外的更新,并且我引用用户的所有查询现在也查询凭据。

老实说,如果我不需要级联删除,我什至不会在用户中引用凭据。如果我在没有 JPA 的情况下这样做,我会这样做。每次删除用户时,我都会设置要删除的凭据,但在用户凭据中没有引用。但是使用 JPA,我只能确保在 User.xml 中添加一个属性时清除 Credential。

无论如何,要求是重要的部分,所以如果你认为我应该使用不同的设计来实现这一点,我完全愿意接受更好的设计。:)

老实说,我希望 JPA 能够使用“引用”作为字段。我的大多数使用 User 的对象实际上只需要他的唯一 ID。但我似乎每次阅读引用实体时都会加载他和凭据(以及用户中的其他 OneToOne 映射)。

提前致谢,

哦,我认为其中一些问题的答案可能是使用带有延迟加载的字节码检测。但我正在使用带有 CTW 和 Intellij 的 Spring。所以当我在 IntelliJ 中调试集成测试时,我真的不知道如何实现这一点。所以那里的任何指示都会很棒。

4

0 回答 0