java - @ManyToMany 关系的 ebean 缓存问题
问题描述
当我尝试使用 ebean 缓存系统(使用 io.ebean:ebean-redis)基本上读取 @ManyToMany 关系时出现异常。这是一个 SpringBoot 应用程序。
我正在使用的版本:
- springBootVersion=2.4.3
- mariaDbVersion=2.7.2
- ebeanVersion=12.7.2
- flywayVersion=7.7.0
BaseModel Java 类:
@MappedSuperclass
public abstract class BaseModel extends Model {
@Id
@GeneratedValue
private Long id;
@WhenCreated
@NotNull
private Instant createdAt;
@WhenModified
@NotNull
private Instant updatedAt;
@NotNull
@SoftDelete
private Boolean deleted = false;
protected BaseModel() {
}
// here the getters and setters
}
文章 Java 类:
@Entity
@Table(name = "article")
@Cache
public class DArticle extends BaseModel {
private static final long serialVersionUID = -7120023327129825322L;
@NotNull
@Index
@Length(20)
private String code;
@DbJson
@NotNull
private Map<Locale, String> name;
@NotNull
private Double unitPrice;
@ManyToMany(mappedBy = "articles")
private List<DArticleCategory> articleCategories;
public DArticle(String code, Map<Locale, String> name, Double unitPrice) {
super();
this.code = code;
this.name = name;
this.unitPrice = unitPrice;
}
// here the getters and setters
}
ArticleCategory Java 类:
@Entity
@Table(name = "article_category")
@Cache
public class DArticleCategory extends BaseModel {
private static final long serialVersionUID = 528512691717594544L;
@DbJson
@NotNull
private Map<Locale, String> name;
@ManyToMany
private List<DArticle> articles;
public DArticleCategory(Map<Locale, String> name) {
super();
this.name = name;
}
// here the getters and setters
}
SQL(我使用 flyway 进行迁移):
create table `article` (
`id` bigint auto_increment not null,
`created_at` datetime(6) not null,
`updated_at` datetime(6) not null,
`deleted` tinyint(1) not null,
`code` varchar(20) not null,
`name` longtext not null,
`unit_price` double not null,
primary key (`id`),
index (`code`)
);
create table `article_category` (
`id` bigint auto_increment not null,
`created_at` datetime(6) not null,
`updated_at` datetime(6) not null,
`deleted` tinyint(1) not null,
`name` longtext not null,
primary key (`id`)
);
我尝试执行的代码:
DArticleCategory c = new DArticleCategory(getTranslatedText("Category 1", "Catégorie 1", null));
c.save();
DArticleCategory cat = articleCategoryRepository.findById(1l);
for (DArticle article : cat.getArticles()) {
//nothing
}
例外:
Caused by: java.lang.RuntimeException: Failed to decode cache data
at io.ebean.redis.encode.EncodePrefixKey.encode(EncodePrefixKey.java:26)
at io.ebean.redis.RedisCache.key(RedisCache.java:85)
at io.ebean.redis.RedisCache.get(RedisCache.java:139)
at io.ebeaninternal.server.deploy.BeanDescriptorCacheHelp.manyPropGet(BeanDescriptorCacheHelp.java:277)
at io.ebeaninternal.server.deploy.BeanDescriptorCacheHelp.manyPropLoad(BeanDescriptorCacheHelp.java:297)
at io.ebeaninternal.server.deploy.BeanDescriptor.cacheManyPropLoad(BeanDescriptor.java:1306)
at io.ebeaninternal.server.loadcontext.DLoadManyContext$LoadBuffer.loadMany(DLoadManyContext.java:215)
at io.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:101)
at io.ebean.common.BeanList.init(BeanList.java:139)
at io.ebean.common.BeanList.iterator(BeanList.java:335)
at db.migration.dev.V2_0_1__katel_test.migrate(V2_0_1__katel_test.java:200)
at org.flywaydb.core.internal.resolver.java.JavaMigrationExecutor.executeOnce(JavaMigrationExecutor.java:61)
... 59 common frames omitted
Caused by: java.lang.IllegalStateException: Expecting String keys but got type:class java.lang.Long
at io.ebean.redis.encode.EncodePrefixKey.encode(EncodePrefixKey.java:19)
... 70 common frames omitted
它看起来是一个非常简单的代码,但我无法看到我错在哪里......
解决方案
注释 @Cacheable 仅适用于允许作为拦截器的公共公开方法。但是如果需要,您可以获得“CacheManager”服务并在您的代码中使用它来在内部处理私有方法中的缓存。但只是为了解决一些“特殊”问题,通常的方法是注释公共方法。
此外,如果您只使用启动器,那么您只使用 Spring 的基本和糟糕的实现,一个简单的内存缓存。
考虑一下您的应用程序将如何工作(单个应用程序、分布式应用程序、缓存的短/长数据量……)以及添加任何受支持缓存管理器(如 ehCache、Hazelcast、Caffeine 等)的依赖项的内存消耗。 . 满足您的要求并提高您的缓存性能。
推荐阅读
- xml - 我们如何在 XSD 中定义任何函数或任何逻辑是可能的?需要在 XSD 中验证 XML 文件的可能性
- batch-file - windows根据条件将文件批量拆分为两个
- javascript - 为 arcgis javascript 插入“esri/dijit/analysis/AggregatePoints”或相关 esri 数字小部件功能所需的理解
- html - 导航栏下拉菜单不展开
- node.js - 什么是用于创建用户的好模式?
- javascript - 为什么它返回不同的结果?(es6箭头函数)
- android - Flutter 无法在 Flutter 上构建发布 APK 文件:1.12.13+hotfix.8
- c - 在等待通过 scanf() 输入之前没有通过 SSH 输出
- mysql - Mysql Query 使用单个查询从三个表中获取记录
- html - 使用 Display Flex 保持方向