-
-
Notifications
You must be signed in to change notification settings - Fork 270
Closed
Milestone
Description
I'm unable to read (deserialize) Class type for nested class and primitives. Storing values to database works, but there is an error while retrieving/loading.
(This is not a big problem for me, because I just found this only in unit testing scenario)
In Java we can have nested classes:
public class ConfigDATest {
// Nested class
public static class TestConfig {
public String name;
public Long def;
public BigDecimal value;
public float f;
}
}When I tried to pass this class to Class type column:
public class DbConfig {
@Column(name = "key", length = 128) @Id @Index(unique = true)
private String key;
@Column(name = "type")
private Class<?> type;
}then it is OK, to store it:
+------------------------------------------------------+
|type |
+------------------------------------------------------+
|java.lang.Integer |
|test.ConfigDATest.TestConfig |
+------------------------------------------------------+
But when Ebean is loading this then there is an error:
Caused by: jakarta.persistence.PersistenceException: Error readSet on test.tables.DbConfig.type
at io.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:527)
at io.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:536)
at io.ebeaninternal.server.query.SqlBeanLoad.load(SqlBeanLoad.java:63)
... 21 more
Caused by: jakarta.persistence.PersistenceException: Unable to find Class test.ConfigDATest.TestConfig
at io.ebeaninternal.server.type.ScalarTypeClass.parse(ScalarTypeClass.java:42)
at io.ebeaninternal.server.type.ScalarTypeClass.convertFromDbString(ScalarTypeClass.java:24)
at io.ebeaninternal.server.type.ScalarTypeClass.convertFromDbString(ScalarTypeClass.java:10)
at io.ebean.core.type.ScalarTypeBaseVarchar.read(ScalarTypeBaseVarchar.java:63)
at io.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:521)
... 23 more
Caused by: java.lang.ClassNotFoundException: test.ConfigDATest.TestConfig
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:421)
at java.base/java.lang.Class.forName(Class.java:412)
at io.ebeaninternal.server.type.ScalarTypeClass.parse(ScalarTypeClass.java:40)
... 27 more
The problem is with io.ebeaninternal.server.type.ScalarTypeClass it uses to serialize: Class#getCanonicalName and to load Class#forName.
This construction for nested class will not work:
Class.forName(TestConfig.class.getName()); // Works
Class.forName(TestConfig.class.getCanonicalName()); // ErrorThis will also not work for primitive types:
Class.forName(int.class.getName()); // Error
Class.forName(int.class.getCanonicalName()); // ErrorExample code:
var q=new DbConfig();
q.setType(int.class);
q.setKey("int_test");
db.insert(q);
var x=db.find(DbConfig.class, "int_test");Here is error:
Caused by: jakarta.persistence.PersistenceException: Unable to find Class int
at io.ebeaninternal.server.type.ScalarTypeClass.parse(ScalarTypeClass.java:42)
at io.ebeaninternal.server.type.ScalarTypeClass.convertFromDbString(ScalarTypeClass.java:24)
at io.ebeaninternal.server.type.ScalarTypeClass.convertFromDbString(ScalarTypeClass.java:10)
at io.ebean.core.type.ScalarTypeBaseVarchar.read(ScalarTypeBaseVarchar.java:63)
at io.ebeaninternal.server.deploy.BeanProperty.readSet(BeanProperty.java:521)
I can make PR with fix for this.
Metadata
Metadata
Assignees
Labels
No labels