Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA未更新返回结果中的多个关系_Jpa - Fatal编程技术网

JPA未更新返回结果中的多个关系

JPA未更新返回结果中的多个关系,jpa,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

以下是我的实体:

@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
所以我的问题是:

当我从一个演员身上取下一部电影并合并该演员,然后检查数据库时,我发现一切正常。假设演员id为5,电影id为3,我看到这些id已从电影演员表中删除

问题是,在我的JSF项目中,虽然我的bean是请求范围的,它们应该获取新信息,但对于电影部分,它们没有。他们还带我去看id=5的电影的id=3的演员。下面是一个示例代码:

@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;
    }
}
@RequestScoped
@命名
公共类FilmTableBackingBean{
@注入
电影刀电影刀;
列出所有电影;
公共列表getAllFilms(){
if(allFilms==null | | allFilms.isEmpty()){
allFilms=filmDao.getAll();
}
归还所有影片;
}
}
如您所见,这是一个请求范围的bean。每次我访问这个bean时,allFilms最初都是空的。因此,从数据库中提取新数据。但是,此获取的数据与数据库中的数据不匹配。它仍然带来了演员

所以我猜这有点像缓存问题

有什么帮助吗

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

编辑:这也没有帮助:

@Entity
public class Film {
    private short filmId;
    @ManyToMany(mappedBy = "films", fetch = FetchType.EAGER)
    public List<Actor> getActors(){
        return actors;
    }
@实体
公共级电影{
私人短片ID;
@ManyToMany(mappedBy=“films”,fetch=FetchType.EAGER)
公共列表getActors(){
返回演员;
}
映射错误

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

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

旁注:为什么要用短字符表示ID?长字符是一个更明智的选择。

映射是错误的

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

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


旁注:为什么要用缩写来表示ID?长是一个更明智的选择。

JB Nizet是正确的,但是您还需要维护关系的双方,因为JPA中有缓存。EntityManager本身缓存托管实体,所以确保您的JSF项目正在关闭并重新获取EntityManager,如果EntityManager长期存在,则清除它们r刷新可能过时的实体。像EclipseLink这样的提供程序也有一个二级缓存,这是正确的,但您还需要维护关系的双方,因为JPA中有缓存。EntityManager本身缓存托管实体,因此确保您的JSF项目正在关闭并重新获取EntityManager,clearing如果它们是长寿命的或刷新的实体,则可能会过时。像EclipseLink这样的提供商也有二级缓存

您好,谢谢您的回答。我只是想让您知道,即使我遇到情况2(“@manytomy(mappedBy=“films”)”),它不起作用。我做错了什么吗?只有在将'em.getEntityManagerFactory().getCache().ReceictAll();'添加到filmDao中的getWithId方法之后,我才能看到更改。您好,很抱歉我的评论。事实证明,因为我是从GeneralDao(filmDao和ActorDao)扩展而来的他们不知何故共享了同一个EntityManager。当他们拥有自己的EntityManager时,我不需要清除缓存。再次感谢!您好,谢谢您的回答。我只是想让您知道,即使我遇到了情况2(“@manytomy(mappedBy=“films”)”),它不起作用。我做错了什么吗?只有在将'em.getEntityManagerFactory().getCache().ReceictAll();'添加到filmDao中的getWithId方法之后,我才能看到更改。您好,很抱歉我的评论。事实证明,因为我是从GeneralDao(filmDao和ActorDao)扩展而来的他们不知何故共享了同一个EntityManager。当他们拥有自己的EntityManager时,我不需要清除缓存。再次感谢!您好,感谢您的回答。只有在添加了他们之后。GetEntityManager工厂().getCache().ReceictAll();要在filmDao中获取WithID,我可以看到更改。但这是唯一的方法吗?我如何知道何时清除缓存,何时不清除?我是否可以永久禁用缓存以确保?(如果db在请求之间没有更改,我已将数据保留在内存中..)抱歉,这似乎是因为ActorDao和FilmDao都是从GeneralDao扩展而来的,并且它们没有自己的实体管理器。您好,谢谢您的回答。只有在添加它们之后。getEntityManagerFactory().getCache().ReceictAll();要在filmDao中获取WithID,我可以看到更改。但这是唯一的方法吗?我如何知道何时清除缓存,何时不清除?我是否可以永久禁用缓存以确保?(如果db在请求之间没有更改,我已将数据保留在内存中..)抱歉,这似乎是因为ActorDao和FilmDao都是从GeneralDao扩展而来的,而且他们没有自己的实体经理。
@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;
    }
}
@Entity
public class Film {
    private short filmId;
    @ManyToMany(mappedBy = "films", fetch = FetchType.EAGER)
    public List<Actor> getActors(){
        return actors;
    }