标签: second-level-cache

Hibernate查询缓存 - 对于不在二级缓存中的对象 - 有风险吗?有用?不好的做法?

与此问题相关

前提:

这些是我的假设,根据我的阅读,经验和理解,他们可能是错的,如果他们是,请评论,我会编辑问题.

  • 查询缓存主要与二级缓存一起使用
  • 查询缓存缓存查询+参数的标识符结果
  • 如果数据库已更改,则查询缓存存在风险,并且未将其反映到缓存中

题:

我有一个不在二级缓存中的对象.由于一些糟糕的编程或其他约束,加载对象的代码在同一个休眠会话中被多次调用.回顾是使用HQL查找查询,例如

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);
Run Code Online (Sandbox Code Playgroud)

在添加查询缓存之前,如果上述代码在同一个Hibernate会话中被调用了N次,那么数据库就会有N次命中

然后我想看看如果添加查询缓存会发生什么:

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();
Run Code Online (Sandbox Code Playgroud)

当我添加查询缓存时,我注意到在同一个会话期间,hibernate不会再次访问数据库N次,每个会话只有一次.

  1. 所以我的第一个假设是Hibernate首先在Session Cache中搜索,然后在2nd Level Cache中搜索.这个假设是否正确?
  2. 我还假设如果Foo不在第二级缓存中的object()在数据库中被更改,那么查询缓存(跨会话范围)将返回错误的标识符,从而返回错误的对象.那是对的吗?
  3. 那么,对于包含不可变信息的查询,即使对于非2L缓存对象,使用查询缓存是否安全可行?(例如,其where子句包含将始终返回相同结果的条件的查询,例如,当ser_num和id对在创建后不更改时,"select p.ser_num where p.id =?")

顺便说一下,在相关问题中声称查询缓存不适用于会话缓存范围.我想知道这个说法或其他什么吗?

hibernate second-level-cache session-cache query-cache

10
推荐指数
1
解决办法
6470
查看次数

为什么我的实体不会从我的二级缓存中被逐出?

我正在使用Hibernate 4.3.11.Final和Spring 3.2.11.RELEASE.我很困惑为什么我的缓存驱逐不起作用.我在DAO中设置了这个...

@Override
@Caching(evict = { @CacheEvict("main") })
public Organization save(Organization organization)
{
    return (Organization) super.save(organization);
}

@Override
@Cacheable(value = "main")
public Organization findById(String id)
{
    return super.find(id);
}
Run Code Online (Sandbox Code Playgroud)

这是我的Spring配置......

<cache:annotation-driven key-generator="cacheKeyGenerator" />

<bean id="cacheKeyGenerator" class="org.mainco.subco.myproject.util.CacheKeyGenerator" />

<bean id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheCacheManager"
    p:cacheManager-ref="ehcache"/>

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    p:configLocation="classpath:ehcache.xml"
    p:shared="true" />

<util:map id="jpaPropertyMap">
    <entry key="hibernate.show_sql" value="true" />
    <entry key="hibernate.dialect" value="org.mainco.subco.myproject.jpa.subcoMysql5Dialect" />
    <entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
    <entry key="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
    <entry key="hibernate.cache.use_second_level_cache" value="true" />
    <entry key="hibernate.cache.use_query_cache" value="false" />
    <entry key="hibernate.generate_statistics" value="true" />
    <entry key="javax.persistence.sharedCache.mode" …
Run Code Online (Sandbox Code Playgroud)

spring hibernate ehcache second-level-cache evict

10
推荐指数
1
解决办法
1583
查看次数

我们可以使用JPA2注释来缓存关联吗?

我现在正在我的实体上使用JPA2 @Cacheable注释,一切都运行良好.

我现在需要缓存ManyToOne关联.

在经典的Hibernate中,有必要注释与@Cache的关联.

@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Student> supervisionGroup;
Run Code Online (Sandbox Code Playgroud)

这很有效.但似乎我们不能在实体本身以外的任何东西上使用JPA2 @Cacheable注释.

我是否遗漏了某些内容,或者JPA委员会是否过于朦胧而无法意识到协会必须被缓存以及实体?当然它不能是昏暗的选择?

hibernate jpa second-level-cache jpa-2.0

9
推荐指数
1
解决办法
3436
查看次数

二级缓存与查询缓存与收集缓存?

根据我的理解,当使用主键加载对象时,将使用二级缓存.这包括获取关联.我只能想到session.get(),session.load方法,其中二级缓存将进入图片.

如果关联是集合或其他实体,它是如何缓存的?例如 :-

  @Cacheable
  public class Department{
   private List Employees;
   private DepatmentDetail detail ;

}
Run Code Online (Sandbox Code Playgroud)

如何使关联员工和详细信息可缓存?我想我需要在协会员工和细节之上提及@cache.但那不起作用?

当开发人员执行department.getEmployees()时,hibernate会在内部触发查询,即

 select * from employees where deptId =1;
Run Code Online (Sandbox Code Playgroud)

现在,如果我使用查询缓存,我明确地进行上述查询并获取结果,将再次向db发出查询.为什么再次触发查询.我认为这与hibernate内部存储二级缓存和查询缓存的结果有关(它们可能存储在不同的区域中).如果有人可以对这方面有所了解,那就太棒了.

java hibernate second-level-cache

9
推荐指数
2
解决办法
1万
查看次数

hibernate如何确保使用数据库中的最新数据更新二级缓存

我已经读过使用hibernate的二级缓存,它可以通过减少数据库命中数据/对象来提高应用程序性能.

但是,hibernate如何确保二级缓存与数据库中的数据保持同步.

例如:

假设下面的类是实体并持久保存到DB中.

@Entity
class User {
    Id
    private int id;
    private String str;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们启用了二级缓存,我理解如果我们打开不同的会话,那么每个会话将访问二级缓存以检索对象值.

现在,如果数据库中的数据发生了变化(例如对于id = 1的行)说某个独立进程/手动更改值,我们尝试访问该值,hibernate如何检测缓存是否具有最新值(对于id = 1).

通常,hibernate如何确保二级缓存中的数据与db值一致.

谢谢你的帮助.

java hibernate second-level-cache

9
推荐指数
2
解决办法
8454
查看次数

Hibernate:清除集合的二级缓存,同时级联删除项目

我有一个问题Hibernate不会为级联删除主题的项目集合更新二级缓存.

细节

假设我们有一个对象Parent,它包含Parent对象的Parent.myChildren集合.现在我们还将人类与Humans.myAllHumans集合以及所有Parent和Child对象放在该集合中.
现在我们session.delete(父)和所有的孩子都从数据库中删除了级联,但是Humans.myAllHumans集合的缓存没有更新!它仍然假设级联删除的对象在数据库中,并且我们在稍后尝试对集合进行迭代时遇到以下异常:
org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行:[foo.Child#751]

尝试了方法

1)我已经尝试过SessionFactory.evictCollection()方法,但据我所知,它不是事务安全且很难从二级缓存中删除数据,我不希望这样.

2)我也可以手动(以编程方式)从myAllHumans集合中删除每个对象.在这种情况下,hibernate会更新第二级缓存.这种方法我想避免,因为它只是使级联删除功能无用.

预期

我希望hibernate足够聪明,可以自动更新集合的缓存.可能吗?
我现在正在使用EhCache,您认为使用其他缓存实现还是配置EhCache可能会有所帮助?

java caching hibernate cascade second-level-cache

8
推荐指数
1
解决办法
6854
查看次数

如何在Hibernate中为延迟加​​载的集合使用二级缓存?

假设我有两个实体,Employee并且Skill.每个员工都有一套技能.现在,当我通过Employee实例懒洋洋地加载技能时,缓存不会用于不同实例中的技能Employee.

让我们考虑以下数据集.

Employee - 1 : Java, PHP
Employee - 2 : Java, PHP
Run Code Online (Sandbox Code Playgroud)

当我在Employee-1之后加载Employee-2时,我不希望hibernate访问数据库以获取技能,而是使用Skill缓存中已有的实例.这可能吗?如果是这样的话?

休眠配置

<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.password">pass</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost/cache</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>

    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.use_query_cache">true</property>
    <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.show_sql">true</property>

    <mapping class="org.cache.models.Employee" />
    <mapping class="org.cache.models.Skill" />
</session-factory>
Run Code Online (Sandbox Code Playgroud)

删除了导入,getter和setter的实体

@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;

    public Employee() {
    } …
Run Code Online (Sandbox Code Playgroud)

java orm hibernate lazy-loading second-level-cache

8
推荐指数
1
解决办法
8327
查看次数

使用SysCache跨会话的NHibernate缓存实体

我正在开发一个Web应用程序,我希望缓存在Web请求中持续存在.我知道第一级缓存只是每个会话.我启用了二级缓存,这适用于查询.

但是,二级缓存似乎不适用于"获取"实体...因此,应用程序所做的大部分数据库工作都不会跨Web请求进行缓存.

这是正常/理想的行为吗?我正在审查一个特定的页面,它会对数据库进行大量的往返,尽管每个查询都很快,如果可以缓存实体,这些似乎是不必要的.

编辑

好的,所以我启用了二级缓存,并且正在进行查询.我似乎无法让它为实体工作.我Cache.Is(c => c.ReadWrite())在我正在测试的主要实体上(流利的nhibernate).但不,它每次都会击中数据库.有任何想法吗?

编辑

我尝试过这样的交易:

public override Accommodation Get(int id) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
        var accomm = Session.Get<Accommodation>(id); 
        tx.Commit(); 
        return accomm; 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

我的映射是这样的(你可以看到我们有一个讨厌的架构):

public void Override(AutoMapping<Core.Entities.Itinerary.Accommodation.Accommodation> mapping)
{
    mapping.HasManyToMany(x => x.Features).Table("AccommodationLinkFeatureType").ChildKeyColumn("FeatureTypeId").NotFound.Ignore();
    mapping.HasManyToMany(x => x.SimilarAccommodation).Table("AccommodationLinkSimilarAccommodation").ChildKeyColumn("SimilarAccommodationId").NotFound.Ignore();
    mapping.HasMany(x => x.TourItinerary).Table("AccommodationTourItinerary");
    mapping.HasOne(x => x.Images).ForeignKey("AccommodationId").Cascade.All().Not.LazyLoad();
    mapping.References(x => x.CollectionType).NotFound.Ignore().Not.LazyLoad();
    mapping.References(x => x.AccommodationUnitType).NotFound.Ignore().Not.LazyLoad();
    Cache.Is(c => c.ReadWrite());
}
Run Code Online (Sandbox Code Playgroud)

但是,这似乎仍然没有从二级缓存中获取.

顺便说一句,我看到很多在线使用的例子,Cache.ReadWrite()但我只能Is在Cache帮助器上看到一个方法,所以我正在尝试Cache.Is(c => c.ReadWrite())- 更改流畅的界面?

nhibernate second-level-cache

8
推荐指数
1
解决办法
1537
查看次数

从单个Web服务器迁移到多个Web服务器负载平衡环境时,Nhibernate二级缓存问题/问题

我之前的设置是单个Web服务器和单个数据库服务器.我正在使用nhibernate二级缓存来缓存内容,以避免大量调用进入数据库.这很有用,因为我正在使用这个组件

nhibernate.caches.syscache
Run Code Online (Sandbox Code Playgroud)

并添加此代码以打开二级缓存(使用常规syscache提供程序):

       return configuration
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ApplicationMap>().Conventions.Add(typeof(Conventions)))
            .ExposeConfiguration(
                c => {
                    c.SetProperty("proxyfactory.factory_class", proxyFactory);
                    c.SetProperty("cache.provider_class", "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache");
                    c.SetProperty("cache.use_second_level_cache", "true");
                    c.SetProperty("cache.use_query_cache", "true");
                    c.SetProperty("expiration", "86400");
                })
            .BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)

我现在已迁移到具有多个Web服务器的新环境,并且我正在尝试了解其含义(我仍然有一个数据库服务器).

由于缓存之前存储在Web服务器上,现在看起来我在每个Web服务器上都有2个并行缓存,它们本身可能不同步并且可能导致过时更新等.

获得之前缓存的好处的最佳解决方案是什么,还可以利用此新设置提供的Web服务器负载平衡的弹性?

nhibernate asp.net-mvc load-balancing fluent-nhibernate second-level-cache

8
推荐指数
1
解决办法
1903
查看次数

如何在Hibernate 4.3中配置二级缓存

我已阅读与此相关的帖子,但没有得到任何答案为我工作.我配置second level cacheHibernate v4.3.,我已经使用MySQL 5.0

我写过以下内容 hibernate.cfg.xml

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
Run Code Online (Sandbox Code Playgroud)

我已经为缓存注释了我的Entity类,如下所示

@Entity 

@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Employee { ....}
Run Code Online (Sandbox Code Playgroud)

运行时会显示以下异常

INFO: HHH000397: Using ASTQueryTranslatorFactory
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.cache.spi.RegionFactory]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:233)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:197)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178)
    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:295)
    at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2442)
    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2438)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1855)
    at com.example.hibernate.Hibernate4Main.main(Hibernate4Main.java:32)
Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.ehcache.EhCacheRegionFactory]
    at org.hibernate.cache.internal.RegionFactoryInitiator.initiateService(RegionFactoryInitiator.java:101)
    at org.hibernate.cache.internal.RegionFactoryInitiator.initiateService(RegionFactoryInitiator.java:46)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:83)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:223)
    ... 7 more
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: …
Run Code Online (Sandbox Code Playgroud)

java hibernate second-level-cache

8
推荐指数
2
解决办法
2万
查看次数