Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot convert List<> of custom class to String in Objectbox #481

Closed
cincospenguinos opened this issue Jun 21, 2018 · 5 comments
Closed
Assignees
Labels
bug Something isn't working
Milestone

Comments

@cincospenguinos
Copy link

Hey guys, I love your project! I'm having trouble getting this to work though. I can't seem to figure out what I'm doing wrong, which is making me wonder if it's a bug.

Issue Basics

  • Using the latest version 1.5.0
  • This occurs every time I attempt to build my project

Reproducing the bug

I have a custom entity class that has two lists of another custom class. I defined a converter for each of those lists to convert the list into a JSON string using Gson. When I attempt to build the project, I'm given the error message Cause: cannot find constructor io.objectbox.relation.ToMany(com.stoicapps.roll4initiative.models.Encounter,io.objectbox.Property).

Code

So the class with the lists is the Encounter class:

@Entity
public class Encounter {

    @Id
    private long id;

    private String name;

    private int currentRound;

    @Convert(converter =  EncounterParticipantConverter.class, dbType = String.class)
    private List<Creature> livingParticipants;

    @Convert(converter =  EncounterParticipantConverter.class, dbType = String.class)
    private List<Creature> deadParticipants;

    private int currentTurnIndex;
    private long uniqueIdentifier;

    ...

Here's the Creature class:

@Entity
public class Creature {

    @Id
    private long id;

    @Convert(converter =  CreatureTypeConverter.class, dbType = Integer.class)
    private CreatureType type;

    @Index
    private String name;

    @Convert(converter = DiceRollConverter.class, dbType = String.class)
    private DiceRoll initiativeDiceRoll;
    private int initiativeValue;

    @Convert(converter = DiceRollConverter.class, dbType = String.class)
    private DiceRoll hitPointsDiceRoll;
    private int hitPointsValue;

Here's the converter for the lists in the Encounter class:

public static class EncounterParticipantConverter implements PropertyConverter<List<Creature>, String> {

        @Override
        public List<Creature> convertToEntityProperty(String jsonString) {
            if (jsonString == null) {
                return null;
            }

            return new Gson().fromJson(jsonString, new TypeToken<List<Creature>>(){}.getType());
        }

        @Override
        public String convertToDatabaseValue(List<Creature> creatureList) {
            if (creatureList == null) {
                return null;
            }

            return new Gson().toJson(creatureList);
        }
    }

Let me know if you need to see anything else.

Logs & stackstraces

Here's the full stack trace:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:objectboxTransformDebugUnitTest'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
	at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)
Caused by: io.objectbox.gradle.transform.TransformException: Could not transform class "com.stoicapps.roll4initiative.models.Encounter" (Could not insert init code for field livingParticipants in constructor)
	at io.objectbox.gradle.transform.ClassTransformer.transformEntityAndBases(ClassTransformer.kt:146)
	at io.objectbox.gradle.transform.ClassTransformer.transformEntities(ClassTransformer.kt:117)
	at io.objectbox.gradle.transform.ClassTransformer.transformOrCopyClasses(ClassTransformer.kt:95)
	at io.objectbox.gradle.transform.ObjectBoxJavaTransform.transform(ObjectBoxJavaTransform.kt:47)
	at io.objectbox.gradle.transform.ObjectBoxAndroidTransform$Registration$injectTransformTask$1.execute(ObjectBoxAndroidTransform.kt:131)
	at io.objectbox.gradle.transform.ObjectBoxAndroidTransform$Registration$injectTransformTask$1.execute(ObjectBoxAndroidTransform.kt:52)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:780)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:747)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
	... 32 more
Caused by: io.objectbox.gradle.transform.TransformException: Could not insert init code for field livingParticipants in constructor
	at io.objectbox.gradle.transform.ClassTransformer.transformConstructors(ClassTransformer.kt:281)
	at io.objectbox.gradle.transform.ClassTransformer.transformEntity(ClassTransformer.kt:186)
	at io.objectbox.gradle.transform.ClassTransformer.transformEntityAndBases(ClassTransformer.kt:142)
	... 46 more
Caused by: javassist.CannotCompileException: [source error] cannot find constructor io.objectbox.relation.ToMany(com.stoicapps.roll4initiative.models.Encounter,io.objectbox.Property)
	at javassist.CtConstructor.insertBeforeBody(CtConstructor.java:273)
	at io.objectbox.gradle.transform.ClassTransformer.transformConstructors(ClassTransformer.kt:279)
	... 48 more
Caused by: compile error: cannot find constructor io.objectbox.relation.ToMany(com.stoicapps.roll4initiative.models.Encounter,io.objectbox.Property)
	at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:749)
	at javassist.compiler.TypeChecker.atNewExpr(TypeChecker.java:149)
	at javassist.compiler.ast.NewExpr.accept(NewExpr.java:73)
	at javassist.compiler.TypeChecker.atFieldAssign(TypeChecker.java:276)
	at javassist.compiler.JvstTypeChecker.atFieldAssign(JvstTypeChecker.java:84)
	at javassist.compiler.TypeChecker.atAssignExpr(TypeChecker.java:230)
	at javassist.compiler.ast.AssignExpr.accept(AssignExpr.java:39)
	at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:242)
	at javassist.compiler.CodeGen.atStmnt(CodeGen.java:330)
	at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
	at javassist.compiler.Javac.compileStmnt(Javac.java:567)
	at javassist.CtConstructor.insertBeforeBody(CtConstructor.java:261)
	... 49 more

Misc

There isn't anything special about my app, especially with what I'm trying to do here.

@cincospenguinos
Copy link
Author

It looks like a good workaround for this issue is to specify a type of List--I changed those fields from List to ArrayList and everything works fine. Regardless, I think overriding the List relation type should work fine, but that of course is up to you guys.

@greenrobot
Copy link
Member

Maybe we can detect the @Convert and skip it for relation detection, @greenrobot-team ?

@greenrobot-team
Copy link
Member

The processor correctly ignores @Convert fields of type List. But the bytecode transformer does not. Guess that bug slipped by, because we have no tests where @Convert is of type List. 😱

Will add those now and work on fix.
-ut

@greenrobot-team greenrobot-team self-assigned this Jul 2, 2018
@greenrobot-team greenrobot-team added the bug Something isn't working label Jul 2, 2018
@greenrobot-team
Copy link
Member

Alright, added tests and built fix. This should be released with the next preview (or final) release of 2.0.0.

Please re-open if the next release does not fix this issue.
-ut

@greenrobot-team greenrobot-team added this to the 2.0 milestone Jul 2, 2018
@greenrobot
Copy link
Member

Try with 2.0.0-beta2

greenrobot-team pushed a commit to objectbox/objectbox-java-generator that referenced this issue Aug 2, 2021
greenrobot-team pushed a commit to objectbox/objectbox-java-generator that referenced this issue Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants