spring-projects / spring-data-cassandra

Provides support to increase developer productivity in Java when using Apache Cassandra. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-cassandra/
Apache License 2.0
374 stars 310 forks source link

`CassandraPersistentPropertyComparator` and `CassandraPrimaryKeyColumnAnnotationComparator` sort properties by column name #1369

Closed akshaysu closed 1 year ago

akshaysu commented 1 year ago

I found that when having composite key in the entity, generated DDL differs when @PrimaryKeyColumn.name is used. spring-data-cassandra version - 4.0.4 java-driver-core - 4.15.0 cassandra server - 4.0.8

Example:

@PrimaryKeyClass
public class PersonKey implements Serializable {
    @PrimaryKeyColumn(name = "firstname", type= PrimaryKeyType.PARTITIONED)
    private String firstName;

    @PrimaryKeyColumn(name="aname", type =  PrimaryKeyType.PARTITIONED)
    private String aName;

    @PrimaryKeyColumn(name="lastname", type = PrimaryKeyType.CLUSTERED)
    private String lastName;

    @PrimaryKeyColumn(name= "bname", type = PrimaryKeyType.CLUSTERED)
    private String bName;
}

Generated DDL is

CREATE TABLE springtest.person (
    aname text,
    firstname text,
    bname text,
    lastname text,
    age text,
    PRIMARY KEY ((aname, firstname), bname, lastname)
) WITH CLUSTERING ORDER BY (bname ASC, lastname ASC)
@PrimaryKeyClass
public class PersonKey implements Serializable {
    @PrimaryKeyColumn(type= PrimaryKeyType.PARTITIONED)
    private String firstName;

    @PrimaryKeyColumn(type =  PrimaryKeyType.PARTITIONED)
    private String aName;

    @PrimaryKeyColumn(type = PrimaryKeyType.CLUSTERED)
    private String lastName;

    @PrimaryKeyColumn(type = PrimaryKeyType.CLUSTERED)
    private String bName;
}

Generated DDL is

CREATE TABLE springtest.person (
    firstname text,
    aname text,
    lastname text,
    bname text,
    age text,
    PRIMARY KEY ((firstname, aname), lastname, bname)
) WITH CLUSTERING ORDER BY (lastname ASC, bname ASC)

It seems issue is not using class field name as column name while ordering the properties of the primary key class Entity. Please confirm whether this is an issue.

Thanks

mp911de commented 1 year ago

It is unfortunate to have the name within the column name comparison, but we always considered the column name as comparison argument. This issue is a bug at its core because we should not sort by column name but rather fall back to the field order.

For the time being, please use @PrimaryKeyColumn(ordinal = …) to provide a sort order for your columns.