pfellwock
pfellwock

Reputation: 41

Sprint-data-Cassandra Mapping of Map with User Defined Type fails with "not of type of the persistent entity"

Here is my User Defined Type in casssandra:

  create type app
  (   app_id uuid,
      app_name varchar,
      maker varchar
   );

And my Table with a Map of such User DefinedType

 create table device 
 (   device_id timeuuid, 
     apps map<uuid,frozen<app>>,

     primary key (device_id) 
);

Its Mapping in Java

@Table("device")
public class Device {

   @PrimaryKey
   @Column("device_id")
   private UUID device_id;


   @Column("apps")
   private Map<UUID, App> apps;

}

And

@UserDefinedType
public class App {

   @Column("app_id")
   private UUID app_id;

   @Column("app_name")
   private String app_name;

   @Column("maker")
   private String maker;

}

Now using a standard Sprind-data-cassandra CrudRepository:

public interface DeviceRepository extends CrudRepository<Device, UUID>{

When I try to save to it as such

    Device st1 = new Device();
    st1.setDevice_id(MyUtils.getRandomTimestampUUID());

    /** Apps **/

    App c1 = new App();
    c1.setApp_id(MyUtils.getRandomTimestampUUID());
    c1.setMaker("Maker of game 1");
    c1.setApp_name("game 1");

    App c2 = new App();
    c2.setApp_id(MyUtils.getRandomTimestampUUID());
    c2.setMaker("Maker of game 2");
    c2.setApp_name("game 2");

    Map<UUID, App> apps = new LinkedHashMap<UUID, App>();
    apps.put(MyUtils.getRandomTimestampUUID(), c1);
    apps.put(MyUtils.getRandomTimestampUUID(), c2);

    st1.setApps(apps);

    _deviceRepository.save(st1);

I get this exception:

 java.lang.IllegalArgumentException: Target bean of type java.util.LinkedHashMap is not of type of the persistent entity (com.pfellwock.cassandra.type.App)!
    at org.springframework.util.Assert.isTrue(Assert.java:68) ~[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.data.mapping.model.BasicPersistentEntity.getPropertyAccessor(BasicPersistentEntity.java:397) ~[spring-data-commons-1.12.2.RELEASE.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.getConvertingAccessor(MappingCassandraConverter.java:608) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.write(MappingCassandraConverter.java:322) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.getWriteValue(MappingCassandraConverter.java:713) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.getWriteValue(MappingCassandraConverter.java:665) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.access$000(MappingCassandraConverter.java:86) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter$2.doWithPersistentProperty(MappingCassandraConverter.java:340) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter$2.doWithPersistentProperty(MappingCassandraConverter.java:335) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:312) ~[spring-data-commons-1.12.2.RELEASE.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.writeInsertFromWrapper(MappingCassandraConverter.java:335) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.writeInsertFromObject(MappingCassandraConverter.java:329) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.write(MappingCassandraConverter.java:314) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.write(MappingCassandraConverter.java:298) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.core.CassandraTemplate.createInsertQuery(CassandraTemplate.java:948) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.core.CassandraTemplate.createInsertQuery(CassandraTemplate.java:717) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.core.CassandraTemplate.doInsert(CassandraTemplate.java:708) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.core.CassandraTemplate.insert(CassandraTemplate.java:290) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]
    at org.springframework.data.cassandra.core.CassandraTemplate.insert(CassandraTemplate.java:285) ~[spring-data-cassandra-1.5.0.BUILD-SNAPSHOT.jar:na]

Here is my setup from gradle:

compile("com.datastax.cassandra:cassandra-driver-core:3.1.1")
compile('org.springframework.boot:spring-boot-starter-data-cassandra')
compile("org.springframework.data:spring-data-cassandra:1.5.0.BUILD-SNAPSHOT")
compile("org.springframework.data:spring-cql:1.5.0.BUILD-SNAPSHOT")

Upvotes: 4

Views: 1921

Answers (1)

sunny
sunny

Reputation: 21

Currentlly spring data does not support custom data type as values in map "app" in your case. Even if you rectify this error you stumble upon other like Only primitive types are allowed inside Collections for property [app] of type [interface java.util.Map] in entity [Device].

As far as this is concern the error will be gone by having "@CassandraType(type = Name.MAP, userTypeName = "address",typeArguments={Name.TEXT,Name.CUSTOM})"

on app property in class device. NOTE* typeArguments in case of map supports only primitive type do CUSTOM is hypothetically added.

Upvotes: 1

Related Questions