我有一个单片的网络服务,我打算随着时间的推移转换成更小的微服务。该应用程序目前使用Grails编写,但微服务并不需要Grails提供的所有内容,因此我们的想法是使用更轻量级的框架(如果有的话)。要从数据库卸载工作,也应使用Hibernate二级缓存。
在任何这种情况发生之前,我开始使用分布式/集群缓存和不同的框架,以了解计划的内容是否真正可行。由于Grails不能一次全部替换,一个测试应用程序用Grails编写,第二个用Spring Boot编写。
两者都配置为使用Hibernate 4.3.11.Final并定义一个简单的域类/ JPA实体。
@Entity
@Table(name = "gr_test_cache")
@Cacheable
public class GrTestCache implements Serializable {
@Id
@GeneratedValue
long id;
@Version
long version;
String name;
// Constructor, Getter, Setter
}
class GrTestCache implements Serializable {
long id
long version
String name
static mapping = {
cache true
}
}
对于缓存,使用Hazelcast v3.7.2,当我在不同的机器上运行任一应用程序时,它们共享缓存,因此从app-1上的DB加载实体会导致app-2上的相同请求从缓存。但是,这仅适用于Spring和Grails应用程序。尝试获取Spring应用程序缓存的实体会导致Grails应用程序出错,反之亦然。
Spring错误读取Grails缓存实体:
java.lang.IllegalArgumentException: Can not set java.lang.String field GrTestCache.name to java.lang.Long
读取Spring缓存实体的Grails错误:
property.BasicPropertyAccessor HHH000123: IllegalArgumentException in class: GrTestCache, setter method of property: version
property.BasicPropertyAccessor HHH000091: Expected type: long, actual value: java.lang.String
不幸的是我还没有找到一个解决方案来查看缓存以查看那里的数据,但对我来说看起来像,虽然域对象似乎是相同的,但两个应用程序在缓存中存储不同的格式这会导致反序列化错误。
现在的问题是:是否有任何方式可以实现这种互操作性,或者我必须坚持使用所有Grails或所有Spring(或其他......)?手动执行缓存以完全控制是不可能的。
修改的
正如所要求的,一些DAO代码。我不认为这是相关的,但是你走了。
SpTestCacheRepository.java
public interface SpTestCacheRepository extends CrudRepository<GrTestCache, Long> {
}
SpTestCacheService.java
@Service
@Transactional
public class SpTestCacheService {
private SpTestCacheRepository cacheRepository;
@Autowired
public SpTestCacheService(SpTestCacheRepository cacheRepository) {
this.cacheRepository = cacheRepository;
}
public GrTestCache testCache(long id) {
return cacheRepository.findOne(id);
}
}
@Transactional
class GrTestCacheService {
def fetchTestCache(def params) {
log.trace "->fetchTestCache <params: $params>"
return GrTestCache.get(params.id)
}
}