使用OneToOne Mapping和其他问题创建共享密钥

时间:2013-06-02 15:49:54

标签: hibernate jpa-2.0 eclipselink

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

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

以下是我的要求:

  1. 每个用户都必须拥有一个凭据,因此它是一对一的。
  2. 该应用仅需要凭据来创建用户并登录
  3. 许多其他对象包含用户(即发票,历史记录,地址等),我不希望每次操作时都会间接加载凭据。
  4. 我希望在清理用户时自动清理凭据。
  5. 所以这是我的第一次尝试:

    @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设置正确,但用户表中还没有行。如果我使凭证可选=真,它神秘地起作用,但我似乎在持久化后获得用户的额外更新,我现在引用用户的所有查询也查询凭证。

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

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

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

    提前致谢,

    哦,我认为其中一些问题的答案可能是使用延迟加载的字节码检测。但是我使用Spring和CTW以及Intellij。因此,当我在IntelliJ中调试集成测试时,我无法弄清楚如何实现这一点。所以任何指针都会很棒。

0 个答案:

没有答案