spring-data-cassandra icon indicating copy to clipboard operation
spring-data-cassandra copied to clipboard

Update UDT set not overwrite object with same hashcode

Open RileyJia opened this issue 3 years ago • 0 comments

Hi, I am fairly new to using this library and I am having this issue with spring-boot-starter-data-cassandra:2.7.0, and I observed this behavior.

The table looks like this:


@Table("student")
@Data
public class Student implements Serializable {

    @NonNull
    @PrimaryKeyColumn(name = "student_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    private String studentId;

    @Column("registed_classes")
    @CassandraType(type = Name.SET, typeArguments = Name.UDT, userTypeName = "registed_class")
    private Set<@Frozen RegistedClass> registedClasses;

    @NonNull
    @Column("last_update_time")
    private Date lastUpdateTime;

}

And the RegistedClass UDT looks like this, it has an attributes map which is not included when calculating equals and hashcode so that every class will be in the set only once:

@UserDefinedType("registed_class")
@EqualsAndHashCode
public class RegistedClass {

    @NonNull
    @Column("class_id")
    private Integer classId;

    @EqualsAndHashCode.Exclude
    @Column("attributs")
    private Map<String, String> attributes;
}

Ths issue I am having is when I try to update one class info in the registeredClasses set using this code:

public boolean updateRegistedClass(String studentId, RegistedClass classInfo) {
    return cassandraTemplate.update(
        Query.query(where("student_id").is(studentId))
            .queryOptions(UpdateOptions.builder().withIfExists().build()),
        Update.empty().addTo("registedClasses").prepend(classInfo)
            .set("last_update_time", new Date()),
        Student.class);
}

Let's say if student has this entry:

student_id: "ABC", registed_Classes:[{class_id: 1, attributes: {"professor": "sss"}}] If I try to update the registeredClass object with new professor info, the value is "aaa". It always appends a new RegistedClass into the set, despite the classes with both professor "aaa" and "sss" having the same hashcode defined in code. (inserting a new object here not just update the attribute map since it's @frozen) And If I do a find() after adding, it will return just one of the classes back, since the hashcode is the same.

So my question here is how I can make The Update function always overwrites what's in the set in the above scenario? And why is find() using the custom hashcode but the update function not.

Thanks

RileyJia avatar Jun 30 '22 22:06 RileyJia