valchkou / cassandra-driver-mapping

JPA addon for DataStax Java Driver for Cassandra
58 stars 24 forks source link

Secondary index recreated even if it already exists #50

Closed DBatOWL closed 9 years ago

DBatOWL commented 9 years ago

We are having trouble with the sync process in that we get a number of "schema not synchronized" messages on application startup. We are using the auto sync feature of this library and no tables have been changed nor have any secondary indexes been altered. What we see in the Cassandra log is that the tables don't change but each index is recreated and it is this change that appears to be causing our out of sync problem. Is this expected, and if it is, is there a way to turn it off so that it only happens if the index has been changed?

The following is an example of a class that is using annotations to describe the indexes:

@Table(name = "messages_by_conversation", //
    indexes = { @Index(columnList = "msgid"), @Index(columnList = "resource"), @Index(columnList = "senderid") })
@TableProperties(values = { @TableProperty("CLUSTERING ORDER BY (deletedOn ASC, timeSent DESC)") })
public class MessagesByConversation {
valchkou commented 9 years ago

No, this is not expected and indexes should not be recreated. please provide the entity class sample which you did above but along with the properties declaration

DBatOWL commented 9 years ago
@Table(name = "messages_by_conversation", //
    indexes = { @Index(columnList = "msgid"), @Index(columnList = "resource"), @Index(columnList = "senderid") })
@TableProperties(values = { @TableProperty("CLUSTERING ORDER BY (deletedOn ASC, timeSent DESC)") })
public class MessagesByConversation {

    @EmbeddedId
    private ConversationMessageKey key;

    @Column(columnDefinition = "timeuuid")
    private UUID msgId;

    @Column
    private String resource;

    @Column
    private String xmppId;

    @Column
    private String xmppThreadId;

    @Column(columnDefinition = "timeuuid")
    private UUID senderId;

    @Column
    private String content;

    @Column
    private Map<UUID, String> addresses;
}

public class ConversationMessageKey {

    @Column(columnDefinition = "timeuuid")
    private UUID convId;

    @Column
    private long deletedOn = 0;

    @Column
    private long timeSent;
}

For briefness I've removed the getters/setters but they all follow the same pattern as follows

    public ConversationMessageKey getKey() {
        return key;
    }

    public MessagesByConversation setKey(ConversationMessageKey value) {
        key = value;
        return this;
    }
DBatOWL commented 9 years ago

BTW, I have the system.log file from a period where the app started that shows the creation/initialization of the indexes. Problem is I don't know how to attach it to the issue, seems I can only attach images, not text files. If you would like a copy of the log, let me know, along with where I can send it, and I'll get it to you.

valchkou commented 9 years ago

I figured the issue: you don't have name for indexes and that's why my program was recreating it each time. CZ name on entity didn't match with name in cassandra. I pushed fix to not recreate the index for the column if it's already in cassandra. Please reload from maven.

p.s. Giving a name to index would also fix it.