一对一单向关系

Chinesewhiteboi

我有两个实体,AP和APStatus,一对一的单向关系。仅AP需要能够访问APStatus。APStatus唯一需要知道的是AP的ID,它也将用作APStatus的主键。本质上,APStatus就像一个嵌入式对象,但是我想要一个单独的表。这是我所拥有的:

我的实体

@Entity
public class AP {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="ID", nullable=false)
    private int id;

    @OneToOne
    private APStatus apStatus;

    //Getters and setters
}

@Entity
public class APStatus {

    @Id
    @Column(name="AP_ID", nullable=false)
    private int apId;

    //Getters and setters
}

我的测试

public class APRepositoryTest {

    @Autowired
    APRepository repository;

    @Autowired
    APStatusRepository statusRepository;

    @Test
    public void test() {
        AP ap = new AP();
        APStatus status = new APStatus();
        statusRepository.save(status);
        ap.setApStatus(status);
        repository.save(ap);
        status.setApId(ap.getId());

        AP dbAp = repository.findOne(ap.getId());
        assertNotNull(dbAp);
        assertNotNull(dbAp.getApStatus());
        assertEquals(dbAp.getId(), dbAp.getApStatus().getApId());
    }

}

assertEquals失败,预期为:<1>,但为<0>。而且我已经知道为什么,在保存状态和ap之后,我要设置状态的apId字段。但是在保存之前对其进行设置的问题在于,我将字段设置为零,因为在repository.save(ap)执行之后,ap的id会自动生成为新值(在本例中为1)。我已经尝试过使关系双向化并添加级联效果,但是到目前为止,我一直没有成功。有人可以指出我正确的方向还是告诉我如何解决这个问题?提前致谢。

编辑:现在,我将使关系成为双向关系,并在apId属性的APStatus类中具有getter方法,如下所示。如果有人有更好的答案,请分享。

public int getApId() { 
    return ap.getId(); 
}
克里斯

首先,您不能更改实体ID。仅一次设置一次即可识别实体。之后,您将强制实例引用完全不同的内容,而JPA不支持该内容。

这意味着,如果status.setApId调用更改了apId字段,则只能使用实际值进行设置。

其次,我不太了解AP的apStatus参考。您的AP是否具有APStatus的外键,或者您打算使用AP.ID APStatus.AP_ID关系?我的猜测是,它打算重用AP.ID APStatus.AP_ID关系,因为这似乎更常见,但仅影响映射方式。

通过先保存AP,在ApStatus中使用其ID并保存,然后更新关系,可以在不更改映射的情况下使它正常工作:

    AP ap = new AP();
    APStatus status = new APStatus();
    repository.save(ap);
    status.setApId(ap.getId());
    statusRepository.save(status);
    ap.setApStatus(status);
    repository.save(ap);

或者,您可以使用JPA 2.0的派生身份更改映射,设置级联设置,然后仅保存AP或APStatus:

@Entity
public class AP {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="ID", nullable=false)
    private int id;

    @OneToOne(mappedBy = "ap", cascade=CascadeType.ALL, orphanRemoval = true)
    private APStatus apStatus;

    //Getters and setters
}

@Entity
public class APStatus {

    @Id
    @OneToOne
    @JoinColumn(name="AP_ID")
    private AP ap;

    //Getters and setters
}

然后,您可以简单地使用:

    AP ap = new AP();
    APStatus status = new APStatus();
    status.setAp(ap);
    ap.setApStatus(status);
    repository.save(ap);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章