与此问题相关
前提:
这些是我的假设,根据我的阅读,经验和理解,他们可能是错的,如果他们是,请评论,我会编辑问题.
题:
我有一个不在二级缓存中的对象.由于一些糟糕的编程或其他约束,加载对象的代码在同一个休眠会话中被多次调用.回顾是使用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次,每个会话只有一次.
Foo不在第二级缓存中的object()在数据库中被更改,那么查询缓存(跨会话范围)将返回错误的标识符,从而返回错误的对象.那是对的吗?顺便说一下,在相关问题中声称查询缓存不适用于会话缓存范围.我想知道这个说法或其他什么吗?
我正在使用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) 我现在正在我的实体上使用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委员会是否过于朦胧而无法意识到协会必须被缓存以及实体?当然它不能是昏暗的选择?
根据我的理解,当使用主键加载对象时,将使用二级缓存.这包括获取关联.我只能想到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内部存储二级缓存和查询缓存的结果有关(它们可能存储在不同的区域中).如果有人可以对这方面有所了解,那就太棒了.
我已经读过使用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值一致.
谢谢你的帮助.
我有一个问题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可能会有所帮助?
假设我有两个实体,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) 我正在开发一个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())- 更改流畅的界面?
我之前的设置是单个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
我已阅读与此相关的帖子,但没有得到任何答案为我工作.我配置second level cache的Hibernate 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)
运行时会显示以下异常
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: …
hibernate ×8
java ×5
nhibernate ×2
asp.net-mvc ×1
caching ×1
cascade ×1
ehcache ×1
evict ×1
jpa ×1
jpa-2.0 ×1
lazy-loading ×1
orm ×1
query-cache ×1
spring ×1