kundera icon indicating copy to clipboard operation
kundera copied to clipboard

Cannot override Persistence Unit keyspace with annotation

Open brandon-mckenzie opened this issue 9 years ago • 6 comments

I am attempting to work with two entities in different keyspaces on the same Cassandra cluster. Since both keyspaces I intend to work with are in the same cluster (and using the Datastax driver by itself allows you to work with multiple keyspaces on the same connection), I figured on being able to get away with using only a single persistence unit, naming the first keyspace property in it since that's required:

kundera.keyspace=keyspace_one

In my entities, I explicitly indicate what keyspace the tables are on:

@Table(name="table_one",schema="keyspace_one@cassandra_pu") @Table(name="table_two",schema="keyspace_two@cassandra_pu")

However, with kundera.ddl.auto.prepare=validate, I find that validation fails because Kundera attempts to work with keyspace_one.table_two, which does not exist.

To figure out why, I went spluenking in com.impetus.kundera.metadata.MetadataUtils and found this:

public static void setSchemaAndPersistenceUnit(EntityMetadata m, String schemaStr, Map puProperties)
    {
        if (schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) > 0) //true in my case
        {
            String schemaName = null;
            if (puProperties != null) //true in my case
            {
                schemaName = (String) puProperties.get(PersistenceProperties.KUNDERA_KEYSPACE);
            }
            if (schemaName == null) //false due to previous if block
            {
                schemaName = schemaStr.substring(0, schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR));
            }
            m.setSchema(schemaName);
            m.setPersistenceUnit(schemaStr.substring(
                    schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) + 1, schemaStr.length()));
        }
        else
        {
            m.setSchema(StringUtils.isBlank(schemaStr) ? null : schemaStr);
        }
    }

Reading this, it looks like the kundera.keyspace value will always take precedence over the annotated keyspace value, which is not desired behavior for my use case, seeing as I wish to override the persistence keyspace for certain entities. As it stands, I am forced to make a new persistence unit for each keyspace I wish to work with.

brandon-mckenzie avatar Jun 09 '16 14:06 brandon-mckenzie

@bmckenzie042188

As of now, Kundera maps each keyspace with one persistence unit. This is supposed to be this way for easy understanding of the structure. We would consider changing it depending on its importance and requirement.

-Karthik

karthikprasad13 avatar Jun 10 '16 10:06 karthikprasad13

That makes sense. However, consider the following situation:

kundera.keyspace=keyspace_one

Entity:

@Table(name="table_one",schema="arbitrary_name_that_doesnt_mean_a_thing@cassandra_pu")

Following the code, schema for table_one is set to kundera.keyspace (keyspace_one), and its persistence unit is set to cassandra_pu. As long as the string contains @ and @ is not the first character in the string, anything before the @ is completely meaningless, which took me going through source code to understand. It may make the structure easier to understand, but it makes the schema attribute on the Table annotation a bit obtuse.

brandon-mckenzie avatar Jul 18 '16 19:07 brandon-mckenzie

Playing with this, this behavior actually worked out for me, as I can externalize my keyspace details and set kundera.keyspace from loaded java properties when I instantiate the EnitityManagerFactories. I guess my only complaint here is that I did not find any documentation indicating that if kundera.keyspace is defined, the schema part of the pattern schema@persistence_unit is completely ignored.

Right now I have two Enitities on two different pu's, each pointing to a different schema:

@Table(name="table_one",schema="schema@cassandra_pu_one")
@Table(name="table_two",schema="schema@cassandra_pu_two")

The schema@ part of these schema names do nothing except offset the @ enough to cause the setSchemaAndPersistenceUnit method to branch in the way I'd like, since I fed the kundera.keyspace property to both of my Entity ManagerFactories independently.

brandon-mckenzie avatar Jul 20 '16 19:07 brandon-mckenzie

Hi,

I have the same issue and, moreover, I would like to reuse the same EntityManagerFactory for more than one EntityManager, since Kundera supports more than one PU in the config file. What I've found is that Kundera does not use the kunder.keyspace property when instantiating the EntityManagers. What I've also found is that Kundera does not enjoy having 2 PUs of the same type (Cassandra, in my case). I've changed Kundera's code to support this but I'm still testing it. If I reach any conclusion, I'll try to submit it for appreciation by the team.

Regards

si24803 avatar May 07 '18 11:05 si24803

Hi @si24803,

Kundera does not enjoy having 2 PUs of the same type

What do you mean by this?

Also, kundera.keyspace should be used when instantiating EntityManagerFactory and not EntityManager. What are you trying to achieve through this?

-Karthik

karthikprasad13 avatar May 08 '18 09:05 karthikprasad13

Hi @karthikprasad13

Sorry @karthikprasad13 , I was wrong when I said that

Kundera does not enjoy having 2 PUs of the same type

It most certainly does as this was the technique I was using and thought it introduced an unnecessary slowness. I wanted to tie both keyspaces toghether in one persistence unit.

What I'm trying to achieve is to use the same EMF for two different keyspaces in Cassandra. I thought I would be able to do it by having one persistence unit in persistence.xml with all my entity classes but, unfortunately, I realised that does not work because the kundera.keyspace property is not passed along to the EntityManagers on EMF.createEntityManager(SynchronizationType, Map). Since the schema annotation in the entity classes does not work, I though I could do it this way. I was wrong. But I think I may have found a solution but I'm still testing it.

Regards

si24803 avatar May 08 '18 18:05 si24803