使用EJB缓存JPA实体
[真正的问题标记为粗体向下。下面是对我的情况的尽可能简短的解释] 我拥有以下JPA实体:使用EJB缓存JPA实体,jpa,ejb,jpa-2.0,ejb-3.1,Jpa,Ejb,Jpa 2.0,Ejb 3.1,[真正的问题标记为粗体向下。下面是对我的情况的尽可能简短的解释] 我拥有以下JPA实体: @Entity Genre{ private String name; @OneToMany(mappedBy = "genre", cascade={CascadeType.MERGE, CascadeType.PERSIST}) private Collection<Novel> novels; } @Entity class Novel{ @ManyToOne(cascade={C
@Entity Genre{
private String name;
@OneToMany(mappedBy = "genre", cascade={CascadeType.MERGE, CascadeType.PERSIST})
private Collection<Novel> novels;
}
@Entity
class Novel{
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST})
private Genre genre;
private String titleUnique;
@OneToMany(mappedBy="novel", cascade={CascadeType.MERGE, CascadeType.PERSIST})
private Collection<NovelEdition> editions;
}
@Entity
class NovelEdition{
private String publisherNameUnique;
private String year;
@ManyToOne(optional=false, cascade={CascadeType.PERSIST, CascadeType.MERGE})
private Novel novel;
@ManyToOne(optional=false, cascade={CascadeType.MERGE, CascadeType.PERSIST})
private Catalog appearsInCatalog;
}
@Entity
class Catalog{
private String name;
@OneToMany(mappedBy = "appearsInCatalog", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
private Collection<NovelEdition> novelsInCatalog;
}
每个实体都使用事务范围的EntityManager关联了一个充当DAO的无状态EJB。例如:
@Stateless
public class NovelDAO extends AbstractDAO<Novel> {
@PersistenceContext(unitName = "XXX")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public NovelDAO() {
super(Novel.class);
}
//NovelDAO Specific methods
}
2) CatalogBuilder是一个有状态EJB,它使用缓存并在每次解析新目录文件时重新初始化,并在保存目录后“删除”
@Stateful
public class CatalogBuilder {
@PersistenceContext(unitName = "XXX", type = PersistenceContextType.EXTENDED)
private EntityManager em;
@EJB
private Cache cache;
private Catalog catalog;
@PostConstruct
public void initialize() {
catalog = new Catalog();
catalog.setNovelsInCatalog(new ArrayList<NovelEdition>());
}
public void addNovelEdition(String title, String genreStr, String publisher, String year){
Genre genre = cache.findGenreCreateIfAbsent(genreStr);//**
Novel novel = cache.findNovelCreateIfAbsent(title, genre);//**
NovelEdition novEd = new NovelEdition();
novEd.setNovel(novel);
//novEd.set publisher year catalog
catalog.getNovelsInCatalog().add();
}
public void setCatalogName(String name) {
catalog.setName(name);
}
@Remove
public void build(){
em.merge(catalog);
}
}
因此,我不知道如何实现缓存。您将如何解决此问题?EclipseLink配置:
- 您可以在配置文件中为所有实体指定属性
- 在实体级别,使用
注释指定不同的属性@Cache
- 在实体级别,使用
注释,将@Cacheable
属性设置为值
真
- 通过
指定检索模式,属性CacheRetrieveMode
启用else使用
旁路
entityManager.setProperty(“javax.persistence.cache.retrieveMode”,CacheRetrieveMode.USE)代码>
- 通过
使用属性CacheStoreMode
,pass
使用
或
配置缓存中的存储刷新
entityManager.setProperty(“javax.persistence.cache.storeMode”,CacheStoreMode.REFRESH)代码>
接口表示共享缓存。要删除所有或某些缓存实体,可以调用其中一个逐出方法。您可以从缓存
获取缓存接口的引用EntityManagerFactory
- 您可以在配置文件中为所有实体指定属性
- 在实体级别,使用
注释指定不同的属性@Cache
- 在实体级别,使用
注释,将@Cacheable
属性设置为值
真
- 通过
指定检索模式,属性CacheRetrieveMode
启用else使用
旁路
entityManager.setProperty(“javax.persistence.cache.retrieveMode”,CacheRetrieveMode.USE)代码>
- 通过
使用属性CacheStoreMode
,pass
使用
或
配置缓存中的存储刷新
entityManager.setProperty(“javax.persistence.cache.storeMode”,CacheStoreMode.REFRESH)代码>
接口表示共享缓存。要删除所有或某些缓存实体,可以调用其中一个逐出方法。您可以从缓存
获取缓存接口的引用EntityManagerFactory
final CatalogBuilder catalogBuilder = //JNDI Lookup
//for each file:
String catalogName = parseCatalogName(file);
catalogBuilder.setCatalogName(catalogName);
//For each novel edition
String title= parseNovelTitle();
String genre= parseGenre();
...
catalogBuilder.addNovelEdition(title, genre, publisher, year);
//End foreach
catalogBuilder.build();
@Stateful
public class CatalogBuilder {
@PersistenceContext(unitName = "XXX", type = PersistenceContextType.EXTENDED)
private EntityManager em;
@EJB
private Cache cache;
private Catalog catalog;
@PostConstruct
public void initialize() {
catalog = new Catalog();
catalog.setNovelsInCatalog(new ArrayList<NovelEdition>());
}
public void addNovelEdition(String title, String genreStr, String publisher, String year){
Genre genre = cache.findGenreCreateIfAbsent(genreStr);//**
Novel novel = cache.findNovelCreateIfAbsent(title, genre);//**
NovelEdition novEd = new NovelEdition();
novEd.setNovel(novel);
//novEd.set publisher year catalog
catalog.getNovelsInCatalog().add();
}
public void setCatalogName(String name) {
catalog.setName(name);
}
@Remove
public void build(){
em.merge(catalog);
}
}
@Stateful
public class Cache {
@PersistenceContext(unitName = "XXX", type = PersistenceContextType.EXTENDED)
private EntityManager em;
@EJB
private sessionbean.GenreDAO genreDAO;
//DAOs for other cached entities
Map<String, Genre> genreName2Object=new TreeMap<String, Genre>();
@PostConstruct
public void initialize(){
for (Genre g: genreDAO.findAll()) {
genreName2Object.put(g.getName(), em.merge(g));
}
}
public Genre findGenreCreateIfAbsent(String genreName){
if (genreName2Object.containsKey(genreName){
return genreName2Object.get(genreName);
}
Genre g = new Genre();
g.setName();
g.setNovels(new ArrayList<Novel>());
genreDAO.persist(t);
genreName2Object.put(t.getIdentifier(), em.merge(t));
return t;
}
}
"passivateEJB(), Exception caught ->
java.io.IOException: java.io.IOException
at com.sun.ejb.base.io.IOUtils.serializeObject(IOUtils.java:101)
at com.sun.ejb.containers.util.cache.LruSessionCache.saveStateToStore(LruSessionCache.java:501)"