Skip to content

Primitives and nested class problem with Class column type #3551

@Ryszard-Trojnacki

Description

@Ryszard-Trojnacki

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());  // Error

This will also not work for primitive types:

        Class.forName(int.class.getName());  // Error
        Class.forName(int.class.getCanonicalName());  // Error

Example 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
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions