Impetus / kundera

A JPA 2.1 compliant Polyglot Object-Datastore Mapping Library for NoSQL Datastores.Please subscribe to:
http://groups.google.com/group/kundera-discuss/subscribe
Apache License 2.0
903 stars 233 forks source link

hard-annotation for schema #315

Closed phillipchengyi closed 11 years ago

phillipchengyi commented 11 years ago

now, it seems in each @Entity, we must have the "schema" hard annotated. by doing this, preventing this entity to be reused by other tools, like hibernate.

i would like to know whether it is possible to have this configured in some kundera or cassandra specific configuration instead in the javax.persistence entity code.

mevivs commented 11 years ago

Currently it is not possible. We will see, if can provide any alternative for this. However schema definition is by default imposed by JPA itself. Ideally it should have been present. Tools like Hibernate have deal with Traditional RDBMSs only. Which more or less offer symmetric symantec. But it certainly differs with various no sql databases.

Will post an update on this, Later.

-Vivek

phillipchengyi commented 11 years ago

Since the schema annotation for kundera is defined as "key space"@"pu name", while in the persistence.xml, we already configured both. persistence-unit name="kundera_cassandra_cld" property name="kundera.keyspace" value="reminder"

so, information is enough there, and also by removing that out of the java code, we can change the db without changing the code and recompile.

mevivs commented 11 years ago

Consider a scenario, say there is an entity Person without schema definition:

@Entity
public class Person
{
     @Column
    private String firstName;
    @Id
    private String id;

// setters and getters
}

Now if persistence.xml contains two persistence units(Cassandra and MongoDB each) as:

<!--  Cassandra persistence unit -->
<persistence-unit name="cass_pu">
        <provider>com.impetus.kundera.KunderaPersistence</provider>
        <properties>
            <property name="kundera.nodes" value="localhost" />
            <property name="kundera.port" value="9160" />
            <property name="kundera.keyspace" value="UUIDCassandra" />
            <property name="kundera.dialect" value="cassandra" />
            <property name="kundera.client" value="pelops" />
            <property name="kundera.client.lookup.class"
                value="com.impetus.client.cassandra.pelops.PelopsClientFactory" />
            <property name="kundera.cache.provider.class"
                value="com.impetus.kundera.cache.ehcache.EhCacheProvider" />
            <property name="kundera.cache.config.resource" value="/ehcache-test.xml" />
        </properties>
    </persistence-unit>

<!--  Mongo persistence unit -->
    <persistence-unit name="mongoTest">
        <provider>com.impetus.kundera.KunderaPersistence</provider>
        <properties>
            <property name="kundera.nodes" value="localhost" />
            <!-- <property name="kundera.nodes" value="192.168.145.168" /> -->
            <property name="kundera.port" value="27017" />
            <property name="kundera.keyspace" value="KunderaExamples" />
            <property name="kundera.dialect" value="mongodb" />
            <property name="kundera.client.lookup.class"
                value="com.impetus.client.mongodb.MongoDBClientFactory" />
            <property name="kundera.ddl.auto.prepare" value="create" />
            <property name="kundera.cache.provider.class"
                value="com.impetus.kundera.cache.ehcache.EhCacheProvider" />
            <property name="kundera.cache.config.resource" value="/ehcache-test.xml" />
            <!-- <property name="kundera.client.property" value="kundera-mongo.properties" 
                /> -->
        </properties>
    </persistence-unit>

Question is, How do we resolve whether Person entity belongs to mongo or Cassandra persistence unit?

-Vivek

phillipchengyi commented 11 years ago

the entity can belong to both persistence unit. since, the operation of entity are via entitymanager, and entitymanager are get from entitymanagerfactory. and entitymanagerfactory are defined by giving the pu name. so while doing operations, which pu is clearly defined.

mevivs commented 11 years ago

True, in case of single persistence unit. But it will not work in case of polyglot persistence scenarios. Where you create an entitmanagerfactory as:

Persistence.createEntityManagerFactory("cass_pu","mongoTest");

-Vivek

phillipchengyi commented 11 years ago

currently by hard coded schema in the java entity, then single entity can't be persistent into different datastore. (so can not support polyglot). if 1 entity can only belong to 1 pu, then you can add it under class tag in that pu's configuration in persistence.xml. like following:

com.impetus.kundera.KunderaPersistence
<class>org.cld.datastore.entity.Category</class>
mevivs commented 11 years ago

True, we did thought about it. But <class> tag is optional, so thought to stick with reusing schema value within @Table annotation.

-Vivek

phillipchengyi commented 11 years ago

but schema value within @Table is also optional, no?

mevivs commented 11 years ago

Yes. So out of these two we have implemented using @Table annotation.

Will discuss within team, if alternative approach by using <class> is implementable.

-Vivek

bsideup commented 11 years ago

+1

it would be very useful, we had the same situation with 2 PUs and shared entities two month ago and it was very painful to copy-paste same entity classes for different PUs.

subes commented 11 years ago

+1

I also like making the schema @Table annotation optional when <class> is specified. Like this, no @PersistenceUnit annotation is needed which I suggested here: https://github.com/impetus-opensource/Kundera/issues/221#issuecomment-23490757

<class> is definitely the most flexible solution to support using the same entity in multiple persistence providers at the same time.

mevivs commented 11 years ago

I see a point here. Looks like, we need to discuss and find a way for this, will plan a discussion and post an update on this.

-Vivek

mevivs commented 11 years ago

Work in progress on this. Suggested changes:

  1. Existing entity definitions will work in same way as previously(Using @Table annotation and schema option)

For Single persistence unit:

  1. @Table annotation will be optional.
  2. Kundera will internally resolve schema and table name(Using kundera.keyspace property in persistence.xml), By default Entity name will be treated as table name unless it is explicitly provided.

Polyglot persistence:

  1. Define specific entity class mapping within <class> tag explicitly.
  2. set to true.
  3. Existing @Table annotation based entities will continue work as previously.

Planned for 2.8 release.

-Vivek

bsideup commented 11 years ago

Glad to hear it! Any estimates?

mevivs commented 11 years ago

2.8 release. Will post an update as soon as i commit this in latest trunk

-Vivek

impetus-opensource-admin commented 11 years ago

Releasing with 2.8