JPA在返回结果时没有更新ManyToMany关系

时间:2013-07-20 07:15:00

标签: jpa

以下是我的实体:

@Entity
public class Actor {

    private List<Film> films;

    @ManyToMany
    @JoinTable(name="film_actor",
    joinColumns =@JoinColumn(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 =@JoinColumn(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是请求作用域,他们应该获取新信息,但对于Film部分,他们没有。他们仍然带给我一个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。每次我访问这个bean时,allFilms最初都是null。因此,从数据库中获取新数据。但是,此提取的数据与数据库中的数据不匹配。它仍然带来了演员。

所以我猜这就像缓存问题。

有任何帮助吗?

编辑:只有在我重新启动服务器后,JPA提取的信息才是正确的。

编辑:这也无济于事:

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

2 个答案:

答案 0 :(得分:2)

映射是错误的。

连接表被映射两次:一次作为多对多关联的连接表,一次作为实体。它是一个或另一个,但不是两个。

多对多也是错误的。一方必须是反面并使用mappedBy属性(因此不定义连接表,该连接表已在关联的另一方面定义)。请参阅示例7.24及其前面的文本the Hibernate documentation(也适用于其他JPA实现)

旁注:为什么要使用ID来做空? A Long将是一个更明智的选择。

答案 1 :(得分:1)

JB Nizet是正确的,但你也需要维护关系的两个方面,因为JPA中存在缓存。 EntityManager本身缓存托管实体,因此请确保您的JSF项目正在关闭并重新获取EntityManagers,如果它们是长期存在的,则清除它们或刷新可能过时的实体。像EclipseLink这样的提供程序也有二级缓存http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching