2013-07-20 97 views
0

沒有更新的多對多關係下面是我的實體:JPA在返回結果

@Entity 
public class Actor { 

    private List<Film> films; 

    @ManyToMany 
    @JoinTable(name="film_actor", 
    joinColumns [email protected](name="actor_id"), 
    inverseJoinColumns = @JoinColumn(name="film_id")) 
    public List<Film> getFilms(){ 
     return films; 
    } 

//... more in here 

繼續前進:

@Entity 
public class Film { 

    private List actors; 

    @ManyToMany 
    @JoinTable(name="film_actor", 
      joinColumns [email protected](name="film_id"), 
      inverseJoinColumns = @JoinColumn(name="actor_id")) 
    public List<Actor> getActors(){ 
     return actors; 
    } 
//... more in here 

和連接表:

@javax.persistence.IdClass(com.tugay.sakkillaa.model.FilmActorPK.class) 
@javax.persistence.Table(name = "film_actor", schema = "", catalog = "sakila") 
@Entity 
public class FilmActor { 
    private short actorId; 
    private short filmId; 
    private Timestamp lastUpdate; 

所以我的問題是:

當我刪除來自Actor的影片併合並該Actor,並檢查數據庫,我發現一切都很好。說演員ID是5,電影ID是3,我看到這些ID是從film_actor表中刪除的。

問題是,在我的JSF項目中,儘管我的bean被請求作用域並且它們應該被假定爲了獲取新的信息,對於電影部分,他們沒有。他們還帶我演員與ID = 3的電影使用id = 5。這裏是一個示例代碼:

@RequestScoped 
@Named 
public class FilmTableBackingBean { 

    @Inject 
    FilmDao filmDao; 

    List<Film> allFilms; 

    public List<Film> getAllFilms(){ 
     if(allFilms == null || allFilms.isEmpty()){ 
      allFilms = filmDao.getAll(); 
     } 
     return allFilms; 
    } 
} 

因此,大家可以看到這是一個請求範圍豆。每次我訪問這個bean時,所有的影片最初都是空的。所以新的數據從數據庫中獲取。但是,此提取的數據與數據庫中的數據不匹配。它仍然帶來演員。

所以我猜這就像緩存問題。

任何幫助?

編輯:只有在重新啓動服務器後,JPA提取的信息纔是正確的。

編輯:這並沒有幫助:

@Entity 
public class Film { 
    private short filmId; 
    @ManyToMany(mappedBy = "films", fetch = FetchType.EAGER) 
    public List<Actor> getActors(){ 
     return actors; 
    } 

回答

1

JB Nizet是正確的,但您還需要維護JPA中緩存的雙方關係。 EntityManager本身緩存託管實體,因此請確保您的JSF項目關閉並重新獲得EntityManagers,如果它們長期存在,則清除它們或刷新可能過時的實體。像EclipseLink這樣的提供商也有二級緩存http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

+0

你好,謝謝你的回答。只有在添加'em.getEntityManagerFactory()。getCache()。evictAll();在filmDao中我能看到變化。但這是唯一的方法嗎?我將如何知道何時清除緩存以及何時不清除?我可以禁用緩存以確保良好嗎? (如果db在請求之間沒有變化,我已經將數據保存在內存中了。) –

+0

對不起,它似乎是因爲ActorDao和FilmDao都從GeneralDao擴展而來,並且他們沒有自己的實體管理器。 –

2

的映射是錯誤的。

連接表被映射兩次:一次作爲多對多關聯的連接表,一次作爲實體。它是一個或另一個,但不是兩個。

並且多對多也是錯誤的。一方必須是反面,並使用mappedBy屬性(並且因此不定義聯合表,該聯合表已經在關聯的另一側擁有定義)。請參閱示例7.24及其前面的文本,the Hibernate documentation(這也適用於其他JPA實現)

附註:爲什麼使用短的ID?龍會是一個明智的選擇。

+0

您好,感謝您的回答。我只是想讓你知道,即使當我有情況2('@ManyToMany(mappedBy =「電影」)'),它不起作用。難道我做錯了什麼?只有在添加'em.getEntityManagerFactory().getCache()。evictAll();'在filmDao中我的getWithId方法,我能看到變化。 –

+0

嗨,對不起,我的評論。事實證明,因爲我從一個GeneralDao(FilmDao和ActorDao)擴展他們在某種程度上共享相同的EntityManager。當他們擁有自己的EntityManagers時,我不需要清除緩存。再次感謝! –