OneToOne关系并不总是获取

时间:2013-07-16 11:03:51

标签: java jpa orm one-to-one

我在两个表之间有一个OneToOne关系,如下所示:

PreRecordLoad.java:

@OneToOne(mappedBy="preRecordLoadId",cascade = CascadeType.ALL)
private PreRecordLoadAux preRecordLoadAux;

PreRecordLoadAux.java:

@JoinColumn(name = "PRE_RECORD_LOAD_ID", referencedColumnName = "PRE_RECORD_LOAD_ID")
@OneToOne
private PreRecordLoad preRecordLoadId;

我正在使用此方法撤回PreRecordLoad对象:

public PreRecordLoad FindPreRecordLoad(Long ID)
{
    print("Finding " + ID + "f");

    Query query;
    PreRecordLoad result = null;
    try
    {
        query = em.createNamedQuery("PreRecordLoad.findByPreRecordLoadId");
        query.setParameter("preRecordLoadId", ID);
        result = (PreRecordLoad)query.getSingleResult();
        //result = em.find(PreRecordLoad.class, ID);
    }
    catch(Exception e)
    {
        print(e.getLocalizedMessage());
    }

    return result;
}

'+'f“'用于查看传递的值是否在某种程度上最终得到了某些东西。它没有。

我最初使用的是em.find,但无论我使用哪种方法,都会出现同样的问题。

我曾经使用BigDecimal作为ID,因为它是默认值,并注意到它在工作时获得精确差异,并且当它不起作用时。具体来说,当它不起作用时精度是4,但是当它没有时它是0。我无法弄清楚为什么会这样,所以我将BigDecimal改为Long,因为我从来没有真正需要它作为BigDecimal。

当我将新的PreRecordLoad和PreRecordLoadAux对象保存到数据库(第一次插入它们),然后尝试运行此方法来调用对象时,它会检索PreRecordLoad,但PreRecordLoadAux为null。这是尽管数据库中的条目以及看起来完全提交的内容,因为我可以从SQLDeveloper访问它,这是一个单独的会话。

但是,如果我停止并重新运行应用程序,那么它会成功撤回两个对象。传递的ID在两次都是相同的,或者至少看起来是。

无论如何,建议将不胜感激,谢谢。

编辑:

以下是我将对象持久保存到数据库中的代码:

    if(existingPreAux==null) {
        try {
            preLoad.setAuditSubLoadId(auditLoad);
            em.persist(preLoad);
            print("Pre Record Load entry Created");

            preAux.setPreRecordLoadId(preLoad);
            em.persist(preAux);
            print("Pre Record Load Aux entry Created");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }
    else {
        try {
            preLoad.setPreRecordLoadId(existingPreLoad.getPreRecordLoadId());
            preLoad.setAuditSubLoadId(auditLoad);
            em.merge(preLoad);
            print("Pre Record Load entry found and updated");

            preAux.setPreRecordLoadAuxId(existingPreAux.getPreRecordLoadAuxId());
            preAux.setPreRecordLoadId(preLoad);
            em.merge(preAux);
            print("Pre Record Load Aux entry found and updated");
        }
        catch(ConstraintViolationException e) {
            for(ConstraintViolation c : e.getConstraintViolations()) {
                System.out.println (c.getPropertyPath() + " " + c.getMessage());
            }
        }
    }

这是在一个方法中,在该代码之后,该方法结束。

1 个答案:

答案 0 :(得分:1)

您有责任保持对象图的一致性。因此,当您执行preAux.setPreRecordLoadId(preLoad);时,您还必须执行preLoad.setPreRecordLoadAux(preAux);

如果不这样做,那么每次从同一会话加载preAux时,都会从第一级缓存中检索它,从而返回错误初始化的实体实例。