2009-09-23 64 views
1

我遇到了一个奇怪的问题,使用JPA的Toplink实现。我正在编写一个独立的应用程序来管理贷款。Java JPA OneToMany - “很多”关系不刷新

我定义了一个与NOTICE类具有OneToMany(双向)关系的LOAN类。我创建了一个GUI来显示特定贷款的所有通知。在我的计划的另一部分,我可以发出延迟通知,并保存为通知。但是,当我尝试显示贷款的所有通知时,迟到通知不会显示。我检查了数据库,并且已经保存了一个条目,但由于某种原因,通知未被取消。

只有当我重新启动我的应用程序时,才会显示此通知。

因为我已经定义了一个OneToMany关系,我自己并没有对数据库进行“直接”查询 - 我让JPA处理为我检索所有通知。

作为一个修复,我创建了一个查询来简单地获取特定贷款的所有通知。这工作。然而,我认为通过定义两个类之间的OneToMany关系,这应该为我处理。看起来好像某些东西没有被正确刷新...就像是在使用“较旧”的通知列表而不是从数据库刷新一样?

+0

你能告诉您的贷款和@OneToMany映射,你要保存的代码? – 2009-09-23 13:39:33

+0

很高兴我的答案能够帮助你,我遇到过几次与不同的ORM一起工作的类似问题。它可能会让人困惑,因为ORM需要处理一个对象生命周期的很多部分,以至于在需要一些额外的代码时很难分辨出来。 – 2009-09-25 15:41:09

回答

4

你是如何“发送迟到的通知”?需要有类似的表述:

MyLoanInstance.listOfNotices.add(MyNoticeInstance); 

即使你已经有一个

MyNoticeInstance.setLoan(MyLoanInstance); 

声明

没有这个电话,你将不得不要么完全刷新你的工作实例与,或重新启动您的应用程序。

当您修改1边时,Eclipselink不会自动更新(直到重新加载所有内容)M 1层关系的M边上的集合,也不会更新1:M关系的1边中的引用if您修改M端的集合。请注意,您应该考虑检查EclipseLink,它是从TopLink发展而来的,您应该可以直接将EclipseLink .jar与TopLink .jar进行交换,只需接收一些折旧警告即可。

Eclipse Link

+0

这工作!当“发出迟到通知”时,我只是在照顾1:M关系的一方 - 正如你上面提到的那样。但是,当我加载贷款来查看发布的不同通知时,我认为我“正在重新加载实例”。当我加载贷款实例时,也许我需要仔细查看我的代码。 – Andre 2009-09-25 13:15:09

+1

谢谢 - 救了我的一天! – Hank 2010-10-19 16:47:49

0

我想

@Entity 
public class Loan { 

    private Integer id; 

    private List<Notice> noticeList; 

    @Id 
    @GeneratedValue 
    public Integer getId() { 
     return this.id; 
    } 

    @OneToMany(mappedBy="loan") 
    public List<Notice> getNoticeList() { 
     return noticeList; 
    } 

} 

@Entity 
public class Notice { 

    private Integer id; 

    private Loan loan; 

    @Id 
    @GeneratedValue 
    public Integer getId() { 
     return this.id; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    public Loan getLoan() { 
     return this.loan; 
    } 

} 

你说

在我的程序的其他部分,我可以送出去这是

也许你保存为一个NOTICE晚通知如下有两个EntityManager实例(一个用于程序的每个部分),因此不会显示最后一条通知保存的内容,因为两个entityManager都不共享相同的持久性维护区t(其中一个不知道另一个发生了什么变化)。你可以做的是明确你的持久化上下文,然后再检索如下

在你的程序的花药部分(坚持您的通知之后)调用

entityManager.flush(); 

而当你想以检索贷款,其注意

entityManager.clear(); 

Query query = entityManager.creatQuery("from Loan l left join fetch l.noticeList where l.id = :id"); 

query.setParameter("id", yourLoanId); 

检查出来,并告诉我它是否工作正常。

问候,

+0

上面描述的贷款和通知实体类与我如何编码它们几乎相同。我最初的解决方法是按照上面的描述创建一个Query,但是我不明白为什么要这么做 - MyLoanInstance.getNoticeList()并没有给我提供与直接查询相同的结果。我认为它的一个“刷新”问题与上面描述的两个entityManager实例有关......但是,我能够用Tnay的建议解决这个问题。 – Andre 2009-09-25 13:25:36

1

您是否尝试过做你的实体管理器冲洗您已经持续了通知后? [entityManager.flush()]