Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The goal of this document is to show implications for tosca model template to move from Eclipse-Link to Hibernate. Primary focus is to show the database compatibility and eventually schema changes where is necessary.
In all these tests I am using some strategies to make sure that tables and fields name generated by Hibernate will be the same as Eclipse-Link.

...

Definitions

  • ElementCollection: Specifies a collection of instances of a basic type or embeddable class. Must be specified if the collection is to be mapped by means of a collection table.
  • OneToMany: Specifies a many-valued association with one-to-many multiplicity. If the collection is defined using generics to specify the element type, the associated target entity type need not be specified; otherwise the target entity class must be specified. If the relationship is bidirectional, the mappedBy element must be used to specify the relationship field or property of the entity that is the owner of the relationship. The OneToMany annotation may be used within an embeddable class contained within an entity class to specify a relationship to a collection of entities. If the relationship is bidirectional, the mappedBy element must be used to specify the relationship field or property of the entity that is the owner of the relationship. When the collection is a java.util.Map, the cascade element and the orphanRemoval element apply to the map value.

...

Control Loop runtime uses persistence.xml file: is the deployment descriptor file for persistence using JPA. It specifies the persistence units and declares the managed persistence classes, the object/relation mapping, and the database connection details.

Hibernate

SpringBoot auto-configuration can automatically scan entity classes. In Control Loop Runtime we can use @EntityScan annotation because entity classes are not placed in the main application package or its sub-packages. In this situation, we need declare the package or list of packages in the main configuration class within @EntityScan annotation.

...

Currently in tosca model template, due the complexity of the schema there are some issues in foreign keys using Collections of String. The SQL code below shows the JpaToscaCapabilityAssignment_ATTRIBUTES table.

Eclipse-Link

MariaDB [controlloop]> SHOW CREATE TABLE JpaToscaCapabilityAssignment_ATTRIBUTES;
+-----------------------------------------+-------------------------------------------------------------------------------------------+
| Table                       | Create Table                                                                              |
+-----------------------------------------+-------------------------------------------------------------------------------------------+
| JpaToscaCapabilityAssignment_ATTRIBUTES | CREATE TABLE `JpaToscaCapabilityAssignment_ATTRIBUTES` (
                                           `name` varchar(120) DEFAULT NULL,
 `version` varchar(20) DEFAULT NULL,
  `ATTRIBUTES` longtext DEFAULT NULL,
`ATTRIBUTES_KEY` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-----------------------------------------+-------------------------------------------------------------------------------------------+

...

ElementCollection should be used with basic type or embeddable class, this example shows side effects using it with entity.

Code Block
languagejava
titleJpaExampleObjMapEc
collapsetrue
@Entity
@Table(name = "ExampleObjMapEc")
@Data
public class JpaExampleObjMapEc implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @ElementCollection
    @Lob
    private Map<@NotNull String, @NotNull JpaExample> examples;
}

...

Map of Objects using ElementCollection (fixed)

The below example shows ElementCollection with embedded class. In order to avoid collisions with field names ("name" and "version"), it has been used AttributeOverride annotation to change their names.

Code Block
languagejava
titleJpaExampleObjMapEc
collapsetrue
@Data
@Embeddable
public class JpaExampleEmd implements Serializable {

    private static final long serialVersionUID = 1L;

    @VerifyKey
    @NotNull
    @AttributeOverride(name = "name", column = @Column(name = "child_name"))
    @AttributeOverride(name = "version", column = @Column(name = "child_version"))
    private ExampleKey key;

    @Column
    private Boolean primed;

    @Column(name = "timeStamp", precision = 3)
    @Temporal(TemporalType.TIMESTAMP)
    @NotNull
    private Date timeStamp;
}

@Entity
@Table(name = "ExampleObjMapEc")
@Data
public class JpaExampleObjMapEc implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @ElementCollection
    private Map<@NotNull String, @NotNull JpaExampleEmd> examples;
}

...

JpaToscaDataType_PROPERTIES table

The SQL code below shows JpaToscaDataType_PROPERTIES table.

Eclipse-Link

MariaDB [controlloop]> describe JpaToscaDataType_PROPERTIES;
+----------------+--------------+------+-----+---------+-------+
| Field          | Type         | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| name           | varchar(120) | YES  |     | NULL    |       |
| version        | varchar(20)  | YES  |     | NULL    |       |
| PROPERTIES     | longblob     | YES  |     | NULL    |       |
| PROPERTIES_KEY | varchar(255) | YES  |     | NULL    |       |
+----------------+--------------+------+-----+---------+-------+

MariaDB [controlloop]> SELECT count(1) FROM `JpaToscaDataType_PROPERTIES`;
+----------+
| count(1) |
+----------+
|       41 |
+----------+

MariaDB [controlloop]> describe ToscaProperty;
+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| DEFAULTVALUE     | varchar(255) | YES  |     | NULL    |       |
| DESCRIPTION      | varchar(255) | YES  |     | NULL    |       |
| ENTRYSCHEMA      | longblob     | YES  |     | NULL    |       |
| REQUIRED         | tinyint(1)   | YES  |     | 0       |       |
| STATUS           | int(11)      | YES  |     | NULL    |       |
| parentLocalName  | varchar(120) | NO   | PRI | NULL    |       |
| localName        | varchar(120) | NO   | PRI | NULL    |       |
| parentKeyVersion | varchar(15)  | NO   | PRI | NULL    |       |
| parentKeyName    | varchar(120) | NO   | PRI | NULL    |       |
| name             | varchar(120) | YES  |     | NULL    |       |
| version          | varchar(20)  | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+

MariaDB [controlloop]>  SELECT count(1) FROM  ToscaProperty;
+----------+
| count(1) |
+----------+
|        0 |
+----------+

...

Right now JpaToscaProperty will generate ToscaProperty table but this one will never used. Move Moving JpaToscaProperty as embeddable class, all max length in varchar fields will be applyapplied.

List of Objects using ElementCollection

ElementCollection should be used with basic type or embeddable class, this example shows side effects using it with entity.

Code Block
languagejava
titleJpaExampleObjListEc
collapsetrue
@Entity
@Table(name = "ExampleObjListEc")
@Data
public class JpaExampleObjListEc implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @ElementCollection
    @Lob
    private List<@NotNull JpaExample> examples;
}

...

List of Objects using ElementCollection (fixed)

The below example shows ElementCollection with embedded class.

Code Block
languagejava
titleJpaExampleObjListEc
collapsetrue
@Entity
@Table(name = "ExampleObjListEc")
@Data
public class JpaExampleObjListEc implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @ElementCollection
    private List<@NotNull JpaExampleEmd> examples;
 }

...

MariaDB [controlloop]> select * from ExampleObjListEc;
+-------------+---------+
| name        | version |
+-------------+---------+
| ExampleList | 1.0.0   |
+-------------+---------+
MariaDB [controlloop]> select * from JpaExampleObjListEc_EXAMPLES;
+-------------+---------+------------+---------------+--------+-----------+
| name        | version | child_name | child_version | primed | timeStamp |
+-------------+---------+------------+---------------+--------+-----------+
| ExampleList | 1.0.0   | example1   | 1.0.0         | NULL   | NULL      |
| ExampleList | 1.0.0   | example2   | 1.0.0         | NULL   | NULL      |
+-------------+---------+------------+---------------+--------+-----------+

Map of Objects using OneToMany

OneToMany is not used in tosca model template. The example below shows an alternative to ElementCollection. In this example there is a field names collision.

Code Block
languagejava
titleJpaExampleObjMap
collapsetrue
@Entity
@Table(name = "ExampleObjMap")
@Data
public class JpaExampleObjMap implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Lob
    private Map<@NotNull String, @NotNull JpaExample> examples;
}

...

Map of Objects using OneToMany (fixed)

The example below shows an alternative to ElementCollection with the fix to avoid field names collision.

Code Block
languagejava
titleJpaExampleObjMap
collapsetrue
@Entity
@Table(name = "ExampleObjMap")
@Data
public class JpaExampleObjMap implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    @VerifyKey
    @NotNull
    private ExampleKey key;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
            joinColumns = {@JoinColumn(name = "parent_name", referencedColumnName = "name"),
                    @JoinColumn(name = "parent_version", referencedColumnName = "version")},
            inverseJoinColumns = {@JoinColumn(name = "child_name", referencedColumnName = "name"),
                    @JoinColumn(name = "child_version", referencedColumnName = "version")})
    private Map<@NotNull String, @NotNull JpaExample> examples;
}

...

MariaDB [controlloop]> select * from ExampleObjMap;
+---------------+---------+
| name          | version |
+---------------+---------+
| ExampleObjMap | 1.0.0   |
+---------------+---------+

MariaDB [controlloop]> select * from Example;
+----------+---------+--------+-----------+
| name     | version | primed | timeStamp |
+----------+---------+--------+-----------+
| example1 | 1.0.0   | NULL   | NULL      |
| example2 | 1.0.0   | NULL   | NULL      |
+----------+---------+--------+-----------+

MariaDB [controlloop]> select * from ExampleObjMap_Example;
+---------------+----------------+------------+---------------+--------------+
| parent_name   | parent_version | child_name | child_version | examples_KEY |
+---------------+----------------+------------+---------------+--------------+
| ExampleObjMap | 1.0.0          | example1   | 1.0.0         | MyKey1       |
| ExampleObjMap | 1.0.0          | example2   | 1.0.0         | MyKey2       |
+---------------+----------------+------------+---------------+--------------+

Multi templates

Right now using Spring repositories it is possible to create more than one service template, as service templates in policy-models/tosca. It works in both Eclipse-Link and Hibernate.

...

  • The presence of longblob types used to store whole objects is definitely not so maintainable. The fix for those issues could be done in both Eclipse-Link and Hibernate. Before to apply the fix it needs to check the max length of varchar fields.
  • Document databases store all information for a given object in a single instance in the database, and every stored object can be different from every other. So, using MongoDB/Cassandra will solve all issues. JpaRepository and MongoRepository extend CrudRepository and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces like e.g. CrudRepository.