Java 添加二级缓存后,Hibernate无法在数据库中找到实体
添加二级缓存后,hibernate将为实体返回null。Hibernate为实体(TrackingItem)返回null,因为它在缓存中找不到多人关系(导航)。当它试图查询数据库以进行导航时,查询返回0行,即使它存在于数据库中。如果没有2级缓存,hibernate可以在数据库中找到实体 这是我的环境:Java 添加二级缓存后,Hibernate无法在数据库中找到实体,java,hibernate,jboss,second-level-cache,infinispan,Java,Hibernate,Jboss,Second Level Cache,Infinispan,添加二级缓存后,hibernate将为实体返回null。Hibernate为实体(TrackingItem)返回null,因为它在缓存中找不到多人关系(导航)。当它试图查询数据库以进行导航时,查询返回0行,即使它存在于数据库中。如果没有2级缓存,hibernate可以在数据库中找到实体 这是我的环境: 服务器:JBoss EAP 6.1 Hibernate 4.2.0.最终版 英菲尼斯潘:5.2.6.4决赛 我反复阅读了《infinspan设置2级缓存指南》 以及关于2级缓存的hibernate
服务器:JBoss EAP 6.1
Hibernate 4.2.0.最终版
英菲尼斯潘:5.2.6.4决赛 我反复阅读了《infinspan设置2级缓存指南》 以及关于2级缓存的hibernate文档 根据Infinispan支持CacheConcurrencyStrategy.TRANSACTIONAL的文档,我目前正在使用容器管理事务的CacheConcurrencyStrategy.TRANSACTIONAL来保持数据库和缓存同步 下面是两个实体(TrackingItem和Navigation),任何不相关的字段和方法都已从实体中删除 TrackingItem.java
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(name = "TRACKING_ITEM")
@IdClass(IdPartitionDateCompositePk.class)
public class TrackingItem extends AbstractEntity<IdPartitionDateCompositePk> {
@Id
@Column(name = "TRACKING_ITEM_ID", nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "TRACKING_ITEM_SEQ_GENERATOR")
@SequenceGenerator(name = "TRACKING_ITEM_SEQ_GENERATOR", sequenceName = "TRACKING_ITEM_SEQ", allocationSize = 1)
private Long id;
@Id
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "PARTITION_DT", nullable = false, updatable = false)
private Date partitionDate = new Date();
@JoinColumn(name = "AVG_ICL_STA_VLD_VAL_ID", referencedColumnName="CLS_VLD_VAL_ID", nullable = false, updatable = false)
@ManyToOne(optional = false)
private ClassificationValidValue averageInclusionStatus;
@OneToOne
@JoinColumns({
@JoinColumn(name = "FILE_ID",nullable = true,updatable = true),
@JoinColumn(name = "FILE_PARTITION_DT",nullable = true,updatable = true)
})
private File file;
@ManyToOne(optional = true)
@JoinColumn(name = "EAE_INCLUSION_STA_VLD_VAL_ID", referencedColumnName="CLS_VLD_VAL_ID", nullable = true, updatable = true)
private ClassificationValidValue exceptionStatus;
//The navigation is not found in the cache and is then queried by hibernate.
@ManyToOne(optional = true)
@JoinColumns({
@JoinColumn(name = "NAVIGATION_ID", nullable = true, updatable = true),
@JoinColumn(name = "NAVIGATION_PARTITION_DT",nullable = true,updatable = true)
})
private Navigation navigation;
@JoinColumn(name = "SOURCE_SYSTEM_ID", nullable = false)
@ManyToOne(optional = false private SonarApplication sourceSystem;
}
<subsystem xmlns="urn:jboss:domain:infinispan:1.4">
<cache-container name="hibernate" default-cache="local-query" module="org.jboss.as.jpa.hibernate:4">
<transport lock-timeout="60000"/>
<local-cache name="local-query">
<transaction mode="NONE"/>
<eviction strategy="LRU" max-entries="100000"/>
<expiration max-idle="300000"/>
</local-cache>
<invalidation-cache name="entity" mode="SYNC">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="100000"/>
<expiration max-idle="300000"/>
</invalidation-cache>
<replicated-cache name="timestamps" mode="ASYNC">
<transaction mode="NONE"/>
<eviction strategy="NONE"/>
</replicated-cache>
</cache-container>
</subsystem>
@可缓存
@缓存(用法=CacheConcurrencyStrategy.TRANSACTIONAL)
@实体
@表(name=“跟踪项目”)
@IdClass(IdPartitionDateCompositePk.class)
公共类TrackingItem扩展了AbstractEntity{
@身份证
@列(name=“TRACKING\u ITEM\u ID”,null=false,updateable=false)
@GeneratedValue(策略=GenerationType.AUTO,生成器=“跟踪项目序列生成器”)
@SequenceGenerator(name=“TRACKING_ITEM_SEQ_GENERATOR”,sequenceName=“TRACKING_ITEM_SEQ”,allocationSize=1)
私人长id;
@身份证
@时态(TemporalType.TIMESTAMP)
@列(name=“PARTITION_DT”,nullable=false,updateable=false)
private Date partitionDate=新日期();
@JoinColumn(name=“AVG_ICL_STA_VLD_VAL_ID”,referencedColumnName=“CLS_VLD_VAL_ID”,nullable=false,updateable=false)
@多通(可选=假)
私有分类有效值平均包含状态;
@奥内托内
@连接柱({
@JoinColumn(name=“FILE_ID”,nullable=true,updateable=true),
@JoinColumn(name=“FILE\u PARTITION\u DT”,nullable=true,updateable=true)
})
私有文件;
@多通(可选=真)
@JoinColumn(name=“EAE\u INCLUSION\u STA\u VLD\u VAL\u ID”,referencedColumnName=“CLS\u VLD\u VAL\u ID”,nullable=true,updateable=true)
私有分类有效值例外状态;
//导航在缓存中找不到,然后由hibernate查询。
@多通(可选=真)
@连接柱({
@JoinColumn(name=“NAVIGATION\u ID”,nullable=true,updateable=true),
@JoinColumn(name=“NAVIGATION\u PARTITION\u DT”,nullable=true,updateable=true)
})
私人导航;
@JoinColumn(name=“SOURCE\u SYSTEM\u ID”,nullable=false)
@manytone(可选=假专用声纳应用程序源系统;
}
Navigation.java
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(name = "NAVIGATION")
@IdClass(IdPartitionDateCompositePk.class)
public class Navigation extends AbstractEntity<IdPartitionDateCompositePk> {
@Id
@Column(name = "NAVIGATION_ID", nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "NAVIGATION_SEQ_GENERATOR")
@SequenceGenerator(name = "NAVIGATION_SEQ_GENERATOR", sequenceName = "NAVIGATION_SEQ", allocationSize = 1)
private Long id;
@Id
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "PARTITION_DT", nullable = false, updatable = false)
private Date partitionDate = new Date();
@JoinColumns({
@JoinColumn(name = "NAVIGATION_ID"),
@JoinColumn(name = "NAVIGATION_PARTITION_DT")
})
@OneToMany
private Set<TrackingItem> trackingItems = new HashSet<TrackingItem>();
}
@可缓存
@缓存(用法=CacheConcurrencyStrategy.TRANSACTIONAL)
@实体
@表(name=“导航”)
@IdClass(IdPartitionDateCompositePk.class)
公共类导航扩展了抽象实体{
@身份证
@列(name=“NAVIGATION\u ID”,null=false,updateable=false)
@GeneratedValue(策略=GenerationType.AUTO,generator=“导航顺序\u生成器”)
@SequenceGenerator(name=“NAVIGATION\u SEQ\u GENERATOR”,sequenceName=“NAVIGATION\u SEQ”,allocationSize=1)
私人长id;
@身份证
@时态(TemporalType.TIMESTAMP)
@列(name=“PARTITION_DT”,nullable=false,updateable=false)
private Date partitionDate=新日期();
@连接柱({
@JoinColumn(name=“NAVIGATION\u ID”),
@JoinColumn(name=“导航分区”)
})
@独身癖
private Set trackingItems=new HashSet();
}
Standalone.xml infinispan子系统中的Hibernate二级缓存配置
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(name = "TRACKING_ITEM")
@IdClass(IdPartitionDateCompositePk.class)
public class TrackingItem extends AbstractEntity<IdPartitionDateCompositePk> {
@Id
@Column(name = "TRACKING_ITEM_ID", nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "TRACKING_ITEM_SEQ_GENERATOR")
@SequenceGenerator(name = "TRACKING_ITEM_SEQ_GENERATOR", sequenceName = "TRACKING_ITEM_SEQ", allocationSize = 1)
private Long id;
@Id
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "PARTITION_DT", nullable = false, updatable = false)
private Date partitionDate = new Date();
@JoinColumn(name = "AVG_ICL_STA_VLD_VAL_ID", referencedColumnName="CLS_VLD_VAL_ID", nullable = false, updatable = false)
@ManyToOne(optional = false)
private ClassificationValidValue averageInclusionStatus;
@OneToOne
@JoinColumns({
@JoinColumn(name = "FILE_ID",nullable = true,updatable = true),
@JoinColumn(name = "FILE_PARTITION_DT",nullable = true,updatable = true)
})
private File file;
@ManyToOne(optional = true)
@JoinColumn(name = "EAE_INCLUSION_STA_VLD_VAL_ID", referencedColumnName="CLS_VLD_VAL_ID", nullable = true, updatable = true)
private ClassificationValidValue exceptionStatus;
//The navigation is not found in the cache and is then queried by hibernate.
@ManyToOne(optional = true)
@JoinColumns({
@JoinColumn(name = "NAVIGATION_ID", nullable = true, updatable = true),
@JoinColumn(name = "NAVIGATION_PARTITION_DT",nullable = true,updatable = true)
})
private Navigation navigation;
@JoinColumn(name = "SOURCE_SYSTEM_ID", nullable = false)
@ManyToOne(optional = false private SonarApplication sourceSystem;
}
<subsystem xmlns="urn:jboss:domain:infinispan:1.4">
<cache-container name="hibernate" default-cache="local-query" module="org.jboss.as.jpa.hibernate:4">
<transport lock-timeout="60000"/>
<local-cache name="local-query">
<transaction mode="NONE"/>
<eviction strategy="LRU" max-entries="100000"/>
<expiration max-idle="300000"/>
</local-cache>
<invalidation-cache name="entity" mode="SYNC">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="100000"/>
<expiration max-idle="300000"/>
</invalidation-cache>
<replicated-cache name="timestamps" mode="ASYNC">
<transaction mode="NONE"/>
<eviction strategy="NONE"/>
</replicated-cache>
</cache-container>
</subsystem>
Persistence.xml属性
<properties>
<property name="jboss.as.jpa.providerModule" value="org.hibernate"/>
<property name="jboss.as.jpa.adapterModule" value="org.jboss.as.jpa.hibernate:4"/>
<property name="jboss.as.jpa.adapterClass" value="org.jboss.as.jpa.hibernate4.HibernatePersistenceProviderAdaptor"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.hbm2ddll.auto" value="validate"/>
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.generate_statistics" value="true" />
<property name="hibernate.cache.use_structured_entries" value="false" />
<property name="hibernate.cache.infinispan.statistics" value="false"/>
<property name="hibernate.cache.infinispan.use_synchronization" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.jboss.as.jpa.hibernate4.infinispan.InfinispanRegionFactory"/>
<property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/hibernate" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
</properties>
最后,这里是一个日志条目,其中hibernate、infinispan和jboss.jdbc.spy被设置为trace,以了解hibernate返回空跟踪项的原因
INFO(com.test.analyze.TrackingItemLinkNode)resolveEntity:ResolvingEntityKey:IdPartitionDateCompositePk{id=2766422,partitionDate=2013-12-21 05:01:15.0}信息(com.test.analyze.TrackingItemLinkNode)resolveEntity:检查cachedEntityMap中的实体。
信息(com.test.analyze.TrackingItemLinkNode)resolveEntity:实体为空。查询该实体。
#对跟踪项目执行实体管理器按id查找
TRACE(org.hibernate.internal.SessionImpl)在时间戳13906093229打开了会话
调试(org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl)由于自动加入检查而跳过JTA同步注册
调试(org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl)已成功注册同步
调试(org.hibernate.ejb.AbstractEntityManagerImpl)寻找要加入的JTA事务
TRACE(org.hibernate.internal.SessionImpl)将刷新模式设置为:自动
TRACE(org.hibernate.internal.SessionImpl)将缓存模式设置为:正常
TRACE(org.hibernate.event.internal.DefaultLoadEventListener)加载实体:(com.test.db.entities.TrackingItem#组件(id,partitionDate){id=2766422,partitionDate=2013-12-21 05:01:15.0})
跟踪(org.hibernate.event.internal.DefaultLoadEventListener)试图解析:(com.test.db.entities.TrackingItem#组件(id,partitionDate){id=2766