-
Notifications
You must be signed in to change notification settings - Fork 7
Adding new data classes
If you need a new data class, it should be implemented as a subclass of the existing ones. It is probably easiest to take a look at the current class structure, and the implementation of the existing classes.
A few things need to be taken into account since we are using an SQL database backend and we are using hibernate as the persistence framework. These are mentioned briefly below.
Instead of primitive types like long
, double
and so on, use the corresponding classes instead, e.g. Long
and Double
. The reason is that they have to be possible to set to null in the SQL table for objects not part of the particular sub class. (They are all in the same big table in the database.)
You need to add some annotations to certain types of data object members.
- Text strings which may contain arbitrarily long strings supplied by the user should be defined as "longtext". The default string definition may be limited to only 255 characters (depending a bit on the SQL database used. For example:
@Column(columnDefinition="longtext")
public String plainTextContent;
- Simple self-defined objects can be embedded if they don't require their own table in the database, i.e. they are intrinsically part of the main object and should not be accessible on their own. For this use the @Embedded annotation. The class itself needs to be tagged as @Embeddable. For example:
@Embedded
public Location location;
- Collections of simple (embeddable) objects need to be annotated with @ElementCollection. For example:
@ElementCollection(targetClass = String.class)
public Set<String> tags;
- Unidirectional many-to-one relationships, e.g. an event may have a link to a single information element, but many events may point to the same information element. It is called unidirectional if the information is only stored in the "many" end using the @ManyToOne annotation. For example:
@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name = "resource_id")
public InformationElement targettedResource;
- Unidirectional one-to-many relationship. Use the @OneToMany annotations. E.g. a message may have many attachments:
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="message_id", referencedColumnName="id")
public List<InformationElement> attachments;
DiMe uses liquibase for managing the SQL database schema, i.e. the definition of the tables and columns in the database. Whenever you have changed or added a data class you need to update the schema so that the SQL database is synchronized with the Java classes. To do this you can simply run:
make updateSchema
This will update the liquibase schema file db.changelog-master.xml by adding the new modification to the end of the file. The entire file contains the full history of changes to the SQL database, so please do not remove any of the existing elements from there. To point of liquibase is that it keeps track of the version of each database installation and is able to upgrade it by comparing with the versioned modification steps found in the schema file.
As an example, let's say we add a foo
string to the Event
class:
public String foo;
After running make updateSchema
these lines have been added to the end of the db.changelog-master.xml
file (try git diff
to see the change):
<changeSet author="mvsjober (generated)" id="1448288259620-1">
<addColumn tableName="EVENT">
<column name="FOO" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
This XML change should be commited to the git repository together with the corresponding Java file change.
Finally, remember to actually apply the new schema to your existing database (otherwise, later schema updates will be confused...). You can apply them e.g. by running DiMe, or running the tests by make test
.