Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Can't use compound/composite keys #216

Closed
eld0 opened this Issue · 13 comments

3 participants

@eld0

Hi,
I've found issue with composite keys. When I'm trying to persist an entity with composite key it always respond with following error:

com.impetus.kundera.KunderaException: InvalidRequestException(why:Unknown identifier user_id)

I'm using kundera 2.4 with cassandra 1.2
Here is my model:

@Entity
@Table(name = "message_links", schema = "test@mto_pu")
@XmlRootElement(name = "MessageLink")
public class MessageLink {

    @EmbeddedId
    private MessageLinkId id;
    @Column(name="body")
    private String messageBody;

    public MessageLink(){}

    public MessageLink(MessageLinkId id, String messageBody) {
        this.id = id;
        this.messageBody = messageBody;
    }
    public MessageLinkId getId() {
        return id;
    }
    public void setId(MessageLinkId id) {
        this.id = id;
    }
    public String getMessageBody() {
        return messageBody;
    }
    public void setMessageBody(String messageBody) {
        this.messageBody = messageBody;
    }
}
@Embeddable
public class MessageLinkId implements Serializable{

    @Column(name="user_id")
    private String userId;
    @Column(name="message_id")
    private String messageId;


    public MessageLinkId(){}

    public MessageLinkId(String userId, String messageId) {
        this.userId = userId;
        this.messageId = messageId;
    }



    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getMessageId() {
        return messageId;
    }
    public void setMessageId(String messageId) {
        this.messageId = messageId;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((messageId == null) ? 0 : messageId.hashCode());
        result = prime * result + ((userId == null) ? 0 : userId.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MessageLinkId other = (MessageLinkId) obj;
        if (messageId == null) {
            if (other.messageId != null)
                return false;
        } else if (!messageId.equals(other.messageId))
            return false;
        if (userId == null) {
            if (other.userId != null)
                return false;
        } else if (!userId.equals(other.userId))
            return false;
        return true;
    }


}

DAO

@Service
public class MessageLinkDAO {
    @PersistenceContext(name="mto_pu")
    private EntityManager entityManager;

    public List<MessageLink> fetchAll(){
        Query query = entityManager.createQuery("Select ml from MessageLink ml",MessageLink.class);
        return query.getResultList();
    }

    public List<MessageLink> find(String userId){
        Query query = entityManager.createQuery("Select ml from MessageLink ml where ml.id.userId = :userId",MessageLink.class);
        query.setParameter("userId", userId);
        return query.getResultList();
    }

    public List<MessageLink> find(String userId,String messageId){
        Query query = entityManager.createQuery("Select ml from MessageLink ml where ml.id.userId = :userId and ml.id.messageId = :messageId",MessageLink.class);
        query.setParameter("userId", userId);
        query.setParameter("messageId", messageId);
        return query.getResultList();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void persist(MessageLink messageLink){
        entityManager.persist(messageLink);
    }

}

Test (it always failed with NPE at persisting step)

@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@ContextConfiguration(locations = {"classpath:application-context.xml"})
public class TestCompoundKeys {

    @Autowired
    private MessageLinkDAO messageLinkDAO;

    @Test
    public void simpleTest(){
        MessageLink messageLink = new MessageLink(new MessageLinkId("test-user-id", "message-id"),"Test message");
        messageLinkDAO.persist(messageLink);

        List<MessageLink> links = messageLinkDAO.find("test-user-id");

        assertNotNull(links);
    }

}

CQL query for table creation

create table message_links(user_id varchar,message_id varchar,body varchar, PRIMARY KEY(user_id,message_id));

But if I drop column family and change kundera.ddl.auto.prepare=create that test will be green and if I start test again it failed with :

Caused by: InvalidRequestException(why:Cannot add already existing column family "message_links" to keyspace "test")
@mevivs
Collaborator

For,

Caused by: InvalidRequestException(why:Cannot add already existing column family "message_links" to keyspace "test")

Looks like ddl.auto.prepare=create is not dropping existing column family. I will verify it.

But not sure about:

com.impetus.kundera.KunderaException: InvalidRequestException(why:Unknown identifier user_id)

This could only happen if "user_id" is not defined within column family as a composite column.

BTW, default comparator class is "BytesType", so you may try changing it to "UTF8Type" by defining as external properties.

-Vivek

@eld0

Hi,
Any news? I have a test project and I can provide it if you wish, maybe it will help.

@xamry
@xamry
@eld0
@xamry
@eld0

Yes, my bad. Done

@xamry
@eld0

Did you try to start test twice? Because, as I said before, if I start it first time it's green for me too, but when I'll start it again, I'll receive an error:

Running com.test.TestCompoundKeys
2013-03-18 14:20:21,071 [ERROR] [main] com.impetus.client.cassandra.schemamanager.CassandraSchemaManager  - Error occurred while creating test Caused by :
InvalidRequestException(why:Cannot add already existing column family "message_links" to keyspace "test")
        at org.apache.cassandra.thrift.Cassandra$execute_cql3_query_result.read(Cassandra.java:37849)
        at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
        at org.apache.cassandra.thrift.Cassandra$Client.recv_execute_cql3_query(Cassandra.java:1562)
        at org.apache.cassandra.thrift.Cassandra$Client.execute_cql3_query(Cassandra.java:1547)
        at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.onCompoundKey(CassandraSchemaManager.java:514)
        at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.addTablesToKeyspace(CassandraSchemaManager.java:427)
        at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.create(CassandraSchemaManager.java:239)
        at com.impetus.kundera.configure.schema.api.AbstractSchemaManager.handleOperations(AbstractSchemaManager.java:278)
        at com.impetus.kundera.configure.schema.api.AbstractSchemaManager.exportSchema(AbstractSchemaManager.java:118)
        at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.exportSchema(CassandraSchemaManager.java:141)
        at com.impetus.kundera.configure.SchemaConfiguration.configure(SchemaConfiguration.java:165)
        at com.impetus.kundera.configure.Configurator.configure(Configurator.java:65)

and if I try to use kundera.ddl.auto.prepare=update instead of "create" - I will always have an NPE during init.
If I create table using script provided previously in the topic and use "validate" - It doesn't work too.

Just checked with cassandra 1.2.3 and result is the same.
I'm running tests and cassandra on Windows machine.

@xamry
@eld0

Thanks a lot!
I've just removed line

<property name="kundera.ddl.auto.prepare" value="validate"/>   

from my persistence.xml and my tests are always green too.
Thanks!

@xamry

Closing this one as issue has been resolved.

@xamry xamry closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.