Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.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
Java 如何使用Hibernate中的读写缓存并发策略保持缓存的多通集合的一致性?_Java_Hibernate - Fatal编程技术网

Java 如何使用Hibernate中的读写缓存并发策略保持缓存的多通集合的一致性?

Java 如何使用Hibernate中的读写缓存并发策略保持缓存的多通集合的一致性?,java,hibernate,Java,Hibernate,在编写“非规范化”集合时,我遇到了非严格读写和读写缓存并发策略之间的差异。。。我的想法是,我有一个作为实体建模的联接表,但它也包含指向它联接到的表的只读链接 我的实体大致如下: @Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) class Actor { @Id Integer id; @Co

在编写“非规范化”集合时,我遇到了非严格读写和读写缓存并发策略之间的差异。。。我的想法是,我有一个作为实体建模的联接表,但它也包含指向它联接到的表的只读链接

我的实体大致如下:

@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Actor {
    @Id
    Integer id;
    @Column
    String name;
}

@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Movie {
    @Id
    Integer id;
    @Column
    String title;
}

@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Credit {
    @Column
    String roleName;

    @ManyToOne(targetEntity = Movie.class, optional = true)
    @JoinColumn(name = "movie_id", insertable = false, updatable = false)
    @NotFound(action = NotFoundAction.IGNORE)
    Movie movie;

    @Column(name = "movie_id")
    Long movieId;

    @ManyToOne(targetEntity = Actor.class, optional = true)
    @JoinColumn(name = "actor_id", insertable = false, updatable = false)
    @NotFound(action = NotFoundAction.IGNORE)
    Actor actor;

    @Column(name = "actor_id")
    Long actorId;
}
启用二级对象缓存(使用ehcache)

我的应用程序写电影和演员。。。后来,它通过写信用证把他们联系在一起。写信用卡时,我只填写roleName、movieId和actorId字段,不提供电影和演员对象

使用非严格的读写缓存,我就能够读回这个Credit对象,它将包含引用的Movie和Actor对象

使用读写缓存,读回信用将返回一个包含空电影和演员字段的信用。如果我清除hibernate缓存,读回该信用卡,然后按预期包含电影和演员对象。这也是事务性缓存的行为(当然不是无缓存)


因此,当使用读写缓存时,hibernate似乎在向具有空Actor和Movie字段的二级缓存中插入积分。是否有办法防止这种情况发生,并始终从数据库中读取以获取这些连接的字段?我已尝试使用CacheConcurrentyStrategy.NONE仅注释字段,但这不起作用

我认为您可能因为奇怪的映射(至少是非标准映射)而偶然发现了一个hibernate bug。没有真正的理由使用两个字段,一个是id字段,另一个是实体字段

您可以使用
session.load
-将id转换为实体引用,它只创建一个代理,不从DB加载数据

如果您删除movieId和actorId字段,并删除movie/actor字段上的可插入/可更新false,则无论
读写
还是
非读写

Credit c = new Credit()
Movie m = session.load(movieId);
Actor a = session.load(actorId);
c.setMovie(m);
c.setActor(a);
session.save(c);
Hibernate不会将完整的对象保存在二级缓存中。我以扁平的形式存储它(水合-更像db表),并从中重建对象。因此,您断言它在缓存中存储了空值的对象,并且没有更新它是不正确的。还有别的事情


读写
非严格读写
之间的主要区别在于,在读写情况下,缓存中的条目将在更新时被锁定,而在非严格读写情况下不会被锁定。只有在多个线程中同时更新此实体时,这才会产生影响

我还要补充一点,不管怎样,数据库中的数据都保存正确。谢谢,这似乎是一个有效的解决办法,但并不完全是我所希望的。我将至少把这个问题留长一点,以防有人知道这是否是一个bug,以及是否有任何方法可以通过操作映射来实现这一点。