Uploaded image for project: 'Hibernate ODM'
  1. Hibernate ODM
  2. HIBERNATE-59

Embedding simple BsonDocument

    • Type: Icon: Task Task
    • Resolution: Unresolved
    • Priority: Icon: Unknown Unknown
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      One of the two main goals of m2 (the other is embedding array) and the more challenging goal.

      Basically we are embedding a Java object whose class is annotated with @Embeddable, but the embedding will end up with a embedded document in one single field, just the opposite of the traditional flattening out behaviour in Hibernate.

      There is another design ticket aiming to avoid the traditional behaviour so we switch to the new embedding behaviour in the scope of this ticket. This ticket assumes that whenever we embed an embeddable object (whose class is annotated with @Embeddable), we aim to embed it as a sub document within one single mongoDB collection entry field. 

      There are multiple ways to go about embedding, we chose STRUCT or User Defined Type for it is a native feature; another option is JSON but it requires JSON library to go about storage and query (could bring about storage inconsistency issue due to different configs between Mongo and JSON library). Support of JSON is out of scope in m2.

       

      Ultimate goal is to store ad-hoc BsonDocument (including nested array or document in arbitrary levels). To simplify management, this ticket only focused on the following behaviour:

      • embed a simple `@Embeddable + @Struct` document with fields of basic types (which are supported by `MongoPreparedStatement` and `MongoResultSet`, as defined in m1), so only one level embedding is required

      For instance, for the following entity class:

      @Entity(name = "Movie")
      @Table(name = "movies")
      static class Movie {
          @Id
          int id;
      
          String title;
      
          Comment comment;
      }
      
      @Embeddable
      @Struct(name = "Comment")
      static class Comment {
      
          @Column(name = "commenter")
          String author;
      
          String content;
          
      } 

       the stored document might be as belows:

      {id: 1, title: 'Perfect Storm', comment: { commenter: 'John Simon', content: 'Fantastic!' } }

      Note that the the `author` field should be stored with the specified column name `commenter`, not `author`.

      The scope of this ticket includes both storage and loading.

      An example testing case in PoC is at https://github.com/NathanQingyangXu/jpa-mongodb-mapping/blob/main/chameleon-core/src/test/java/org/hibernate/omm/type/struct/StructTests.java. Note that it shows the ultimate goal of storing arbitrary document, but it is easily tweaked to showcase the end result of this ticket.  

      Hibernate extension points:

      • STRUCT type needs to be registered in Dialect

      • getAggregateSupport() method should be overridden in Dialect

      PoC PR (which aims the ultimate goal so refer selectively) is at https://github.com/NathanQingyangXu/jpa-mongodb-mapping/pull/40.

            Assignee:
            valentin.kovalenko@mongodb.com Valentin Kavalenka
            Reporter:
            nathan.xu@mongodb.com Nathan Xu
            None
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: