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. TheOneToMany
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, themappedBy
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 ajava.util.Map
, thecascade
element and theorphanRemoval
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.
...
ElementCollection should be used with basic type or embeddable class, this example shows side effects using it with entity.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@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; } |
...
MariaDB [controlloop]> SHOW CREATE TABLE JpaExampleObjMapEc_EXAMPLES;
+-----------------------------+-------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
| JpaExampleObjMapEc_EXAMPLES | CREATE TABLE `JpaExampleObjMapEc_EXAMPLES` (
`EXAMPLES_KEY` varchar(255) DEFAULT NULL,
`PRIMED` tinyint(1) DEFAULT 0,
`timeStamp` varchar(255) DEFAULT NULL,
`child_name` varchar(255) DEFAULT NULL,
`child_version` varchar(255) DEFAULT NULL,
`name` varchar(120) DEFAULT NULL,
`version` varchar(20) DEFAULT NULL,
KEY `FK_JpaExampleObjMapEc_EXAMPLES_name` (`name`,`version`),
CONSTRAINT `FK_JpaExampleObjMapEc_EXAMPLES_name` FOREIGN KEY (`name`, `version`)
REFERENCES `ExampleObjMapEc` (`name`, `version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
...
MariaDB [controlloop]> SHOW CREATE TABLE JpaExampleObjMapEc_EXAMPLES;
+-----------------------------+-------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
| JpaExampleObjMapEc_EXAMPLES | CREATE TABLE `JpaExampleObjMapEc_EXAMPLES` (
`name` varchar(120) NOT NULL,
`version` varchar(20) NOT NULL,
`child_name` varchar(255) DEFAULT NULL,
`child_version` varchar(255) DEFAULT NULL,
`primed` bit(1) DEFAULT NULL,
`timeStamp` datetime(6) DEFAULT NULL,
`examples_KEY` varchar(255) NOT NULL,
PRIMARY KEY (`name`,`version`,`examples_KEY`),
CONSTRAINT `FKeu2s8p9mhstus32uliuwib8rr` FOREIGN KEY (`name`, `version`)
REFERENCES `ExampleObjMapEc` (`name`, `version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
...
Map of Objects using ElementCollection (hacked)
In this scenario JpaExampleEmd JpaExampleLob class is not entity and neither embedded.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Data public class JpaExampleEmdJpaExampleLob implements Serializable { private static final long serialVersionUID = 1L; @VerifyKey @NotNull private ExampleKey key; private Boolean primed; @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 @Lob private Map<@NotNull String, @NotNull JpaExampleEmd>JpaExampleLob> examples; } |
JpaToscaDataType_PROPERTIES table
The SQL code below shows JpaToscaDataType_PROPERTIES table.
Eclipse-Link
Hibernate
MariaDB [controlloop]> SHOW CREATE describeTABLE JpaToscaDataTypeJpaExampleObjMapEc_PROPERTIESEXAMPLES;
+----------------+--------------+------+-----+---------+-----------------------------------------------------------------------------------+
| Table | Create Table |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
| JpaExampleObjMapEc_EXAMPLES | CREATE TABLE `JpaExampleObjMapEc_EXAMPLES` (
`name` varchar(120) NOT NULL,
`version` varchar(20) NOT NULL,
`examples` longblob DEFAULT NULL,
`examples_KEY` varchar(255) NOT NULL,
PRIMARY KEY (`name`,`version`,`examples_KEY`),
CONSTRAINT `FKeu2s8p9mhstus32uliuwib8rr` FOREIGN KEY (`name`, `version`)
REFERENCES `ExampleObjMapEc` (`name`, `version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-----------------------------+-------------------------------------------------------------------------------------------------------+
After saving an example:
MariaDB [controlloop]> select * from JpaExampleObjMapEc_EXAMPLES;
+-----------------+---------+---------------------------+--------------+
| name | version | examples | examples_KEY |
+-----------------+---------+---------------------------+--------------+
| ExampleObjMapEc | 1.0.0 | .... <binary code> .... | MyKey1 |
| ExampleObjMapEc | 1.0.0 | .... <binary code> .... | MyKey2 |
+-----------------+---------+---------------------------+--------------+
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. Moving JpaToscaProperty as embeddable class, all max length in varchar fields will be applied.
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 | ||||||
---|---|---|---|---|---|---|
| ||||||
@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; } |
...
MariaDB [controlloop]> select * from ExampleObjListEc;
+-------------+---------+
| name | version |
+-------------+---------+
| ExampleList | 1.0.0 |
+-------------+---------+
MariaDB [controlloop]> select * from JpaExampleObjListEc_EXAMPLES;
+-------------+---------+---------------------------+
| name | version | EXAMPLES |
+-------------+---------+---------------------------+
| ExampleList | 1.0.0 | .... <binary code> .... |
| ExampleList | 1.0.0 | .... <binary code> .... |
+-------------+---------+---------------------------+
Hibernate
MariaDB [controlloop]> describe ExampleObjListEc;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| name | varchar(120) | NO | PRI | NULL | |
| version | varchar(20) | NO | PRI | NULL | |
+---------+--------------+------+-----+---------+-------+
MariaDB [controlloop]> SHOW CREATE TABLE JpaExampleObjListEc_EXAMPLES;
+------------------------------+------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------------------+------------------------------------------------------------------------------------------------------+
| JpaExampleObjListEc_EXAMPLES | CREATE TABLE `JpaExampleObjListEc_EXAMPLES` (
`name` varchar(120) NOT NULL,
`version` varchar(20) NOT NULL,
`examples_name` varchar(120) NOT NULL,
`examples_version` varchar(20) NOT NULL,
UNIQUE KEY `UK_8nnxsomci4yiwc8ks6radimiq` (`examples_name`,`examples_version`),
KEY `FK1a58hldurq1910ne2hbm9a7af` (`name`,`version`),
CONSTRAINT `FK1a58hldurq1910ne2hbm9a7af` FOREIGN KEY (`name`, `version`)
REFERENCES `ExampleObjListEc` (`name`, `version`),
CONSTRAINT `FKnj1lga10so090q9wf38k4jf7p` FOREIGN KEY (`examples_name`, `examples_version`)
REFERENCES `Example` (`name`, `version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+------------------------------+------------------------------------------------------------------------------------------------------+
...
MariaDB [controlloop]> select * from ExampleObjListEc;
+-------------+---------+
| name | version |
+-------------+---------+
| ExampleList | 1.0.0 |
+-------------+---------+
MariaDB [controlloop]> select * from JpaExampleObjListEc_EXAMPLES;
+--------+-----------+------------+---------------+-------------+---------+
| PRIMED | timeStamp | child_name | child_version | name | version |
+--------+-----------+------------+---------------+-------------+---------+
| NULL | NULL | example1 | 1.0.0 | ExampleList | 1.0.0 |
| NULL | NULL | example2 | 1.0.0 | ExampleList | 1.0.0 |
+--------+-----------+------------+---------------+-------------+---------+
Hibernate
MariaDB [controlloop]> SHOW CREATE TABLE JpaExampleObjListEc_EXAMPLES;
+------------------------------+------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------------------+------------------------------------------------------------------------------------------------------+
| JpaExampleObjListEc_EXAMPLES | CREATE TABLE `JpaExampleObjListEc_EXAMPLES` (
`name` varchar(120) NOT NULL,
`version` varchar(20) NOT NULL,
`child_name` varchar(255) DEFAULT NULL,
`child_version` varchar(255) DEFAULT NULL,
`primed` bit(1) DEFAULT NULL,
`timeStamp` datetime(6) DEFAULT NULL,
KEY `FK1a58hldurq1910ne2hbm9a7af` (`name`,`version`),
CONSTRAINT `FK1a58hldurq1910ne2hbm9a7af` FOREIGN KEY (`name`, `version`)
REFERENCES `ExampleObjListEc` (`name`, `version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+------------------------------+------------------------------------------------------------------------------------------------------+
...
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 |
+---------------+----------------+------------+---------------+--------------+
Hibernate
MariaDB [controlloop]> SHOW CREATE TABLE ExampleObjMap_Example;
...
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.
...
- Move to Hibernate with EclipseLink tables is possible.
- The presence of longblob types used to store whole objects is an issues, it is readable only by Java language or by any other language compatible with Java binary code. I am not sure if a db-migrator can handle that.
- 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
andMongoRepository
extendCrudRepository
and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces like e.g.CrudRepository
.