Impetus / kundera

A JPA 2.1 compliant Polyglot Object-Datastore Mapping Library for NoSQL Datastores.Please subscribe to:

Home Page:http://groups.google.com/group/kundera-discuss/subscribe

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NullOrInvalidEntityRule - entity metadata is always null (Kundera mongo 3.12)

limpid-kzonix opened this issue · comments

NullOrInvalidEntityRule - metadata is always null

public boolean validate(E entity)
    {
        if (entity != null)
        {
            // entity metadata could be null.
            if (entityMetadata == null)
            {
                throw new IllegalArgumentException(
                        "Entity object is invalid, operation failed. Please check previous log message for details");
            }

            return false;

        }

        // will return false if entity is null.
        return true;
    }

@Data
@Entity
@Table(name = "person", schema = "testDB@defaultPersistenceUnit")
public class Person {

  @Id
  @Column(name = "id")
  private String id;

  private String name;

}

    final EntityManagerFactory defaultPersistenceUnit = Persistence.createEntityManagerFactory("defaultPersistenceUnit");
    final EntityManager entityManager = defaultPersistenceUnit.createEntityManager();
    final Person person = new Person();
    entityManager.persist(person);
    return ok(Json.toJson(person));

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">

  <persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>com.impetus.kundera.KunderaPersistence</provider>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="kundera.nodes" value="localhost"/>
      <property name="kundera.port" value="27017"/>
      <property name="kundera.keyspace" value="testDB"/>
      <property name="kundera.dialect" value="mongodb"/>
      <property name="kundera.annotations.scan.package" value="models"/>
      <property name="kundera.ddl.auto.prepare" value="create"/>
      <property name="kundera.client.lookup.class" value="com.impetus.client.mongodb.MongoDBClientFactory"/>
    </properties>
  </persistence-unit>

</persistence>

Hi @limpid-kzonix,

Add entity classes in persistence.xml if you wanna load selected entities for this particular persistence unit.

Or remove <exclude-unlisted-classes>true</exclude-unlisted-classes> from persistence unit to load all entities in the classpath.

@devender-yadav, I also tried to add entities to persistence.xml
image
And also tried to without is, just only use property name="kundera.annotations.scan.package. But stil the same exception. I all cases.

com.impetus.kundera.metadata.KunderaMetadataManager

I found out that List<String> persistenceUnits always null (in method as shown below)

/**
     * Finds ands returns Entity metadata for a given array of PUs.
     * 
     * @param entityClass
     *            the entity class
     * @param persistenceUnits
     *            the persistence units
     * @return the entity metadata
     */
    public static EntityMetadata getEntityMetadata(final KunderaMetadata kunderaMetadata, Class entityClass)
    {
        if (entityClass == null)
        {
            throw new KunderaException("Invalid class provided " + entityClass);
        }
        List<String> persistenceUnits = kunderaMetadata.getApplicationMetadata().getMappedPersistenceUnit(entityClass);

        // persistence units will only have more than 1 persistence unit in case
        // of RDBMS.
        if (persistenceUnits != null)
        {
            for (String pu : persistenceUnits)
            {
                MetamodelImpl metamodel = getMetamodel(kunderaMetadata, pu);
                EntityMetadata metadata = metamodel.getEntityMetadata(entityClass);
                if (metadata != null && metadata.getPersistenceUnit().equals(pu))
                {
                    return metadata;
                }
            }
        }
        if (log.isDebugEnabled())
            log.warn("No Entity metadata found for the class " + entityClass
                    + ". Any CRUD operation on this entity will fail."
                    + "If your entity is for RDBMS, make sure you put fully qualified entity class"
                    + " name under <class></class> tag in persistence.xml for RDBMS "
                    + "persistence unit. Returning null value.");

        return null;
        // throw new KunderaException("Unable to load entity metadata for :" +
        // entityClass);
    }

@limpid-kzonix you have persistence.xml under META-INF folder available in the classpath?

@devender-yadav, i debugged all flow of initialazing pu, and yes, persistence.xml is under META-INF folder available in the classpath, and in my case pu mongoUnit recognized as well.

Check out https://github.com/Impetus/Kundera#sample-projects and download kundera-mongodb-example.zip. Its very basic example with CRUD operation. You can start with this.

OR send your sample project so that we can replicate your issue.

If you are using above sample project, make sure to use Kundera 3.12 as the example is using an older version.

play-java-jpa-example.zip
It is simple sbt application with using playframework.

It is strange. Sample project works fine ( without any exceptions ). I think that issue related to integration with playframewok (or some internal logic of play had a bad influence on some flow of Kundera, or also its depended to diff project structure of play-application). Or probably I did something wrong. @devender-yadav, try to reproduce this issue with my project. I will look forward to your feedback.

Hi @limpid-kzonix,

Please check https://dzone.com/articles/play-nosql-building-nosql

Useful part

If you’re running Play! in development mode, Play! uses its own Classloader that doesn’t read classes from target/scala-2.xx/classes folder. As a result, your User entity won’t be loaded at runtime and EntityMetadata should not be null error thrown.
In order to make your entity classes available at runtime (in development mode, of course), all you’ve to do is to create jar file out of them and put this jar file into lib folder under project root directory. (create lib folder as it won’t exist by default)

(modified for simplification)

@limpid-kzonix,

Also, mention entity classes and <exclude-unlisted-classes>true</exclude-unlisted-classes> in persistence.xml

Check sample -https://github.com/Impetus/Kundera/wiki/Using-Kundera-with-Play!-Framework#write-persistencexml

And mention schema in Entity

Example:

@Table(name = "users", schema = "KunderaExamples@cassandra_pu")

If you’re running Play! in development mode

Hmm, I tested with play in prod mode.
image
And the same issue
image

play.api.UnexpectedException: Unexpected exception[KunderaException: java.lang.IllegalArgumentException: Entity object is invalid, operation failed. Please check previous log message for details]

@limpid-kzonix did you make changes in entity and persistence.xml? It's working at my end in prod mode

@devender-yadav, I found my previous project with play and Kundera. And found out that for play is required to set entity classes and <exclude-unlisted-classes>true</exclude-unlisted-classes> in persistence.xml. And everything works fine (prod mode)

So I think that this issue can be closed, only one remark. It would be better to add these specific instructions to the wiki page in play section, also update the guide with the latest play version, and zip with the sample project.

@limpid-kzonix Thanks for the feedback. We will update wiki accordingly.