[hibernate-dev] Question about substituting IDs in Hibernate OGM

Gunnar Morling gunnar at hibernate.org
Thu Feb 12 03:42:37 EST 2015


2015-02-12 1:37 GMT+01:00 Haswell, Josiah D <Josiah.Haswell at ca.com>:

>  Perfect.  That worked—thanks for the help!
>

Cool :)


> I’ve made some pretty good progress—you can save entities and some
> associations, and retrieve some properties lazily.  Unfortunately, I’m
> having a bit of trouble with getting access to all of the type information
> I need.
>
>
>
>
>
> In particular, say you have the hierarchy:
>
>
>
>
>
> @Inheritance(strategy = InheritanceType.*TABLE_PER_CLASS*)  (1)
>
> @Entity
>
> @Table(name = “persistable”)
>
> Public class Persistable {
>
> @Id
>
> @GeneratedValue(strategy = GenerationType.IDENTITY)
>
> Long id;
>
>
>
> @Basic
>
> String persistableName;
>
>
>
>
>
> }
>
>
>
>
>
> @Entity
>
> @Table(“person_table”)
>
> Public class Person extends Persistable {
>
>
>
> @Basic
>
> @Column(name = “first_name”)
>
> String firstName;
>
>
>
> @Basic
>
> @Column
>
> String lastName;
>
>
>
> }
>
>
>
> I need to generate the schema:
>
>
>
> :persistable/persistableName
>
>
>
> :Person/first_name
>
> :Person/lastName
>


TABLE_PER_CLASS is meant to create a table for each type of the hierarchy
with *all* its attributes. So actually you'd have to generate the following
schema:

    :Persistable/persistableName

    :Person/persistableName
    :Person/first_name
    :Person/lastName

We also support SINGLE_TABLE which creates one table for all the types of
the hierarchy, so the schema would have to be the following:

    :Persistable/persistableName
    :Persistable/first_name
    :Persistable/lastName
    :Persistable/DTYPE //denotes the entity type

Atm. we don't support JOINED (which may be what you had in mind).

And access it from a few contexts.
>
>
>
>
>
> *Schema Definition*
>
>
>
> When generating the schema, I need to be able to get the table name, which
> I was able to from the EntityPersisters available in SessionFactoryImpl.
> From there, I needed to be able to get each property on each class, its
> type, and its alias (as defined by @Column), which I couldn’t figure out
> how to do.  I looked through both the EntityMetamodel and the
> ClassMetamodels on each persister, but it wasn’t clear how to get that.
>
>
>
> Looking in the ClassMetadata, I found the property names, but that
> included all of the properties for all of the linear supertypes of the
> associated entity.
>
> Looking at the EntityMetamodel, I found I could get all of the properties,
> but I couldn’t figure out how to filter out the properties declared in the
> current entity type.
>
>
>
> I ended up scanning the annotations again to get the information I needed
> to generate the schema, which doesn’t seem like a good solution.
>

Schema definition is still a weak point in OGM atm., the grid dialects we
began with tend to have no strong schema. There is the SchemaDefiner
contract which you need to implement for this (and make known via
YourDatastoreProvider#getSchemaDefinerType()). In
YourSchemaDefiner#initializeSchema() you can obtain everything you need
e.g. like so:

    @Override
    public void initializeSchema(Configuration configuration,
SessionFactoryImplementor factory) {
        Iterator<PersistentClass> classMappings = configuration
.getClassMappings();

        while ( classMappings.hasNext() ) {
            PersistentClass mapping = classMappings.next();
            Table table = mapping.getTable();

            Iterator<Column> columnIterator = table.getColumnIterator();
            while(columnIterator.hasNext()) {
                Column column = columnIterator.next();
                String columnName = column.getName();

                // do something with column...
            }
        }
    }

Note that this API stems straight from Hibernate ORM and is not exactly
what we'd like to have for Hibernate OGM. So be prepared for changes in
this area in future revisions (the entire SchemaDefiner contract is
considered experimental atm., also Configuration will go away in Hibernate
ORM in the future), but for now it should allow you to do the right thing.
Definitely better than doing manual annotation scanning :)


> Now, I’m running into the same problem retrieving a tuple:
>
>
>
>
>
>
>
> public Tuple getTuple(EntityKey k, TupleContext c) {
>
> final Long id = getOrThrowUnexpectedId(k);
>
> final Entity entity = retrieveEntity(id);
>
> return new Tuple(*new LazyEntityBackedTupleSnapshot(entity, tupleContex*
> t));
>
> }
>
>
>
>
>
> public class LazyEntityBackedTupleSnapshot implements TupleSnapshot {
>
> final Entity entity;
>
> final TupleContext context;
>
> //constructor, etc.
>
>
>
> public Object get(String column) {
>
> *return entity.get(column);*
>
>
>
> }
>
>
>
>
>
> }
>
>
>
>
>
> Now, the problem is, say the entity that I retrieved was a Person.  If I
> call *p.getPersistableName() , *then entity.get(column) needs to be
>
> Entity.get(“:persistable/persistableName”) to get the value.  I could
> search through the linear supertypes of the current type if I could get
> it.  I notice that the actual TupleContext that I’m getting has an
> OptionsContextImpl with an entity type that I can use to search for the
> appropriate entity type, but that’s private, and I don’t want to use
> reflection to get it.
>

See above, you should take all the column values from the Person table (or
the Persistable table when working with SINGLE_TABLE). You can get the
table name from the given entity key. From the tuple context btw. you can
get the columns we actually need, so you don't need to fetch any unmapped
columns from the datastore.


> I’m sure I’m just missing some cool feature of OGM here, and couldn’t find
> it looking through the other implementations.  Any additional help would be
> fantastic.
>
>
>
> Thanks!
>

No problem. Hope it helps,

--Gunnar

*From:* gunnar.morling at googlemail.com [mailto:gunnar.morling at googlemail.com]
> *On Behalf Of *Gunnar Morling
> *Sent:* Wednesday, February 11, 2015 12:43 AM
> *To:* Haswell, Josiah D
> *Cc:* hibernate-dev at lists.jboss.org
> *Subject:* Re: [hibernate-dev] Question about substituting IDs in
> Hibernate OGM
>
>
>
> Hi Josiah,
>
>
>
> It's great to hear that you are working an a backend for Hibernate OGM!
>
>
>
> Regarding ids, it should work for you if they are mapped using the
> IDENTITY strategy:
>
>
>
>     @Id
>
>     @GeneratedValue(strategy=GenerationType.IDENTITY)
>
>     Long id;
>
>
>
> This causes the Hibernate ORM engine to read back the id value generated
> by the datastore upon insertion. To make it work, your GridDialect for OGM
> needs to implement the IdentityColumnAwareGridDialect facet [1]. You can
> check out the MongoDB dialect for an example.
>
>
>
> If this works and this kind of id generation is the only one which is
> useful for Datomic (i.e. table/sequence strategies don't make any sense),
> you may validate mapped entities by means of a SchemaDefiner [2] (an
> experimental contract of OGM). An example is CouchDBSchemaDefiner.
>
>
>
> Let us know how it goes or in case you run into any other issues.
>
>
>
> --Gunnar
>
>
>
> [1]
> https://github.com/hibernate/hibernate-ogm/blob/master/core/src/main/java/org/hibernate/ogm/dialect/identity/spi/IdentityColumnAwareGridDialect.java
>
> [2]
> https://github.com/hibernate/hibernate-ogm/blob/master/couchdb/src/main/java/org/hibernate/ogm/datastore/couchdb/impl/CouchDBSchemaSchemaDefiner.java
>
>
>
>
>
>
>
> 2015-02-11 2:40 GMT+01:00 Haswell, Josiah D <Josiah.Haswell at ca.com>:
>
> Hi folks,
>
> I'm creating a Hibernate OGM implementation for Datomic, and I have a
> question about IDs.
>
> Say I have the entity
>
> @Entity
> public class Person {
> @Id
> @GeneratedValue
> Long id;
>
>
> }
>
> In Datomic, you have to assign a temporary ID before submitting the
> transaction.  Datomic will then return the actual persistence ID after the
> transaction has completed.  My question is, how can I get the actual ID
> back into the entity?
>
> Thanks!
>
> Josiah
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
>
>


More information about the hibernate-dev mailing list