Netflix / astyanax

Cassandra Java Client
Apache License 2.0
1.04k stars 355 forks source link

@Serializer is ignored if field type map/set or another @Entity #586

Open evilezh opened 9 years ago

evilezh commented 9 years ago

I thought if I specify explicit @Serializer, then it is used no matter of field type.

Column columnAnnotation = field.getAnnotation(Column.class);
    if ((columnAnnotation != null)) {
        field.setAccessible(true);
        ColumnMapper columnMapper = null;
        Entity compositeAnnotation = field.getType().getAnnotation(Entity.class);
        if (Map.class.isAssignableFrom(field.getType())) {
            columnMapper = new MapColumnMapper(field);
        } else if (Set.class.isAssignableFrom(field.getType())) {
        columnMapper = new SetColumnMapper(field);
        } else if(compositeAnnotation == null) {
            if (columnAnnotation.unique()) {
                Preconditions.checkArgument(tempUniqueMapper == null, "can't have multiple unique columns '" + field.getName() + "'");
               tempUniqueMapper = new LeafColumnMapper(field);
           } else {
               columnMapper = new LeafColumnMapper(field);
           }
    } else {
        columnMapper = new CompositeColumnMapper(field);
    }
    Preconditions.checkArgument(!usedColumnNames.contains(columnMapper.getColumnName()), 
        String.format("duplicate case-insensitive column name: %s", columnMapper.getColumnName().toLowerCase()));
    columnList.put(columnMapper.getColumnName(), columnMapper);
    usedColumnNames.add(columnMapper.getColumnName().toLowerCase());

As per code it first checks Set.class Map.class Entity.class .. and select corresponding Mappers which ignore @Serializer annotation. LeafColumnMapper respects @Serializer, but because of pre-conditions we do not get to it.

Something like:

@Entity
class MyClass(){}

@Column
@Serializer(MySerializer.class)
Set<MyClass> data;

will not work and @Serializer is ignored ... and

@Column
@Serializer(MySerializer.class)
MyClass data;

as MyClass is @Entity .. @Serializer is also ignored.

So - I suggest always first check @Serializer and only after built-in methods.