diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactEntry.java b/ccm-cms/src/main/java/org/librecms/assets/ContactEntry.java
new file mode 100644
index 000000000..992a48da2
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/ContactEntry.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * A contact entry for adding data to a {@link ContactableEntity}.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "CONTACT_ENTRIES", schema = DB_SCHEMA)
+public class ContactEntry implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "CONTACT_ENTRY_ID")
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long contactEntryId;
+
+ /**
+ * Determines the order of the contact entries.
+ */
+ @Column(name = "ENTRY_ORDER")
+ private long order;
+
+ /**
+ * Key used to identify the entry.
+ */
+ @Column(name = "ENTRY_KEY", length = 255, nullable = false)
+ private String key;
+
+ /**
+ * The value of the entry.
+ */
+ @Column(name = "ENTRY_VALUE", length = 4096)
+ private String value;
+
+ public ContactEntry() {
+ super();
+
+ order = 0;
+ }
+
+ public long getContactEntryId() {
+ return contactEntryId;
+ }
+
+ protected void setContactEntryId(final long contactEntryId) {
+ this.contactEntryId = contactEntryId;
+ }
+
+ public long getOrder() {
+ return order;
+ }
+
+ public void setOrder(final long order) {
+ this.order = order;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 89 * hash + (int) (contactEntryId ^ (contactEntryId >>> 32));
+ hash = 89 * hash + (int) (order ^ (order >>> 32));
+ hash = 89 * hash + Objects.hashCode(key);
+ hash = 89 * hash + Objects.hashCode(value);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof ContactEntry)) {
+ return false;
+ }
+ final ContactEntry other = (ContactEntry) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (contactEntryId != other.getContactEntryId()) {
+ return false;
+ }
+ if (order != other.getOrder()) {
+ return false;
+ }
+ if (!Objects.equals(key, other.getKey())) {
+ return false;
+ }
+ return Objects.equals(value, other.getValue());
+ }
+
+ public boolean canEqual(final Object obj) {
+
+ return obj instanceof ContactEntry;
+ }
+
+ @Override
+ public final String toString() {
+ return toString("");
+ }
+
+ public String toString(final String data) {
+
+ return String.format("%s{ "
+ + "contactEntryId = %d, "
+ + "order = %d"
+ + "key = \"%s\", "
+ + "value = \"%s\"%s"
+ + " }",
+ super.toString(),
+ contactEntryId,
+ order,
+ key,
+ value,
+ data);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactableEntity.java b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntity.java
new file mode 100644
index 000000000..6ceb8a555
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntity.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.CascadeType;
+import org.librecms.contentsection.Asset;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderBy;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * Base class for contactable entities.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "CONTACTABLE_ENTITIES", schema = DB_SCHEMA)
+public class ContactableEntity extends Asset {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Contact data for this entity.
+ */
+ @OneToMany
+ @JoinColumn(name = "CONTACTABLE_ID")
+ @OrderBy("order")
+ @Cascade(CascadeType.ALL)
+ private List contactEntries;
+
+ /**
+ * The postal address.
+ */
+ @OneToOne
+ @JoinColumn(name = "POSTAL_ADDRESS_ID")
+ private PostalAddress postalAddress;
+
+ public ContactableEntity() {
+
+ super();
+
+ contactEntries = new ArrayList<>();
+ }
+
+ public List getContactEntries() {
+ return Collections.unmodifiableList(contactEntries);
+ }
+
+ protected void addContactEntry(final ContactEntry contactEntry) {
+
+ contactEntries.add(contactEntry);
+ }
+
+ protected void removeContactEntry(final ContactEntry contactEntry) {
+
+ contactEntries.remove(contactEntry);
+ }
+
+ public void setContactEntries(final List contactEntries) {
+ this.contactEntries = new ArrayList<>(contactEntries);
+ }
+
+ public PostalAddress getPostalAddress() {
+ return postalAddress;
+ }
+
+ protected void setPostalAddress(final PostalAddress postalAddress) {
+ this.postalAddress = postalAddress;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 59 * hash + Objects.hashCode(this.contactEntries);
+ hash = 59 * hash + Objects.hashCode(this.postalAddress);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+
+ if (!(obj instanceof ContactableEntity)) {
+ return false;
+ }
+ final ContactableEntity other = (ContactableEntity) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (!Objects.equals(this.contactEntries, other.getContactEntries())) {
+ return false;
+ }
+ return Objects.equals(this.postalAddress, other.getPostalAddress());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+ return obj instanceof ContactableEntity;
+ }
+
+ @Override
+ public String toString(final String data) {
+
+ return super.toString(String.format(
+ "contactEntries = { %s }, "
+ + "postalAddress = %s%s",
+ Objects.toString(contactEntries),
+ Objects.toString(postalAddress),
+ data));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java
new file mode 100644
index 000000000..f388fb2e8
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import org.librecms.contentsection.AssetRepository;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+/**
+ * Manager class providing methods for adding and removing {@link ContactEntry}
+ * and {@link PostalAddress} to and from a {@link ContactableEntity}.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class ContactableEntityManager {
+
+ @Inject
+ private AssetRepository assetRepository;
+
+ public void addContactEntryToContactableEntity(
+ final ContactEntry contactEntry,
+ final ContactableEntity contactableEntity) {
+
+ if (contactEntry.getOrder() == 0) {
+ contactEntry
+ .setOrder(contactableEntity.getContactEntries().size());
+ }
+ contactableEntity.addContactEntry(contactEntry);
+ assetRepository.save(contactableEntity);
+ }
+
+ public void removeContactEntryFromContactableEntity(
+ final ContactEntry contactEntry,
+ final ContactableEntity contactableEntity) {
+
+ contactableEntity.removeContactEntry(contactEntry);
+ assetRepository.save(contactableEntity);
+ }
+
+ public void addPostalAddressToContactableEntity(
+ final PostalAddress postalAddress,
+ final ContactableEntity contactableEntity) {
+
+ contactableEntity.setPostalAddress(postalAddress);
+ assetRepository.save(postalAddress);
+ }
+
+ public void removePostalAddressFromContactableEntity(
+ final PostalAddress postalAddress,
+ final ContactableEntity contactableEntity) {
+
+ contactableEntity.setPostalAddress(null);
+ assetRepository.save(postalAddress);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/assets/Organization.java b/ccm-cms/src/main/java/org/librecms/assets/Organization.java
new file mode 100644
index 000000000..e0e06891c
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/Organization.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import java.util.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * A reusable piece of information about an organization.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "ORGANIZATIONS", schema = DB_SCHEMA)
+public class Organization extends ContactableEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ @Column(name = "NAME", length = 1024)
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 37 * hash + Objects.hashCode(name);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (!(obj instanceof Organization)) {
+ return false;
+ }
+ final Organization other = (Organization) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ return Objects.equals(name, other.getName());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+
+ return obj instanceof Organization;
+ }
+
+ @Override
+ public String toString(final String data) {
+
+ return super.toString(String.format(
+ "name = \"%s\"%s",
+ name,
+ data));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/assets/Person.java b/ccm-cms/src/main/java/org/librecms/assets/Person.java
new file mode 100644
index 000000000..bd94b04be
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/Person.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import java.time.LocalDate;
+import java.util.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * An asset representing a person.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "PERSONS", schema = DB_SCHEMA)
+public class Person extends ContactableEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The surname/familyname of the person
+ */
+ @Column(name = "SURNAME")
+ private String surname;
+
+ /**
+ * The given name of the person.
+ */
+ @Column(name = "GIVEN_NAME")
+ private String givenName;
+
+ /**
+ * Any prefixes to the name of the person. Examples are Prof. or Dr.
+ */
+ @Column(name = "NAME_PREFIX")
+ private String prefix;
+
+ /**
+ * Any suffixes to the name of the person. Examples for suffixes are
+ * PhD, or especially for Great Britain the membership in various orders,
+ * for example KBE or CBE.
+ */
+ @Column(name = "SUFFIX")
+ private String suffix;
+
+ /**
+ * The birthdate of the person.
+ */
+ @Column(name = "BIRTHDATA")
+ private LocalDate birthdate;
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(final String surname) {
+ this.surname = surname;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public void setGivenName(final String givenName) {
+ this.givenName = givenName;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(final String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getSuffix() {
+ return suffix;
+ }
+
+ public void setSuffix(final String suffix) {
+ this.suffix = suffix;
+ }
+
+ public LocalDate getBirthdate() {
+ return birthdate;
+ }
+
+ public void setBirthdate(final LocalDate birthdate) {
+ this.birthdate = birthdate;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 37 * hash + Objects.hashCode(surname);
+ hash = 37 * hash + Objects.hashCode(givenName);
+ hash = 37 * hash + Objects.hashCode(prefix);
+ hash = 37 * hash + Objects.hashCode(suffix);
+ hash = 37 * hash + Objects.hashCode(birthdate);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+
+ if (!(obj instanceof Person)) {
+ return false;
+ }
+ final Person other = (Person) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (!Objects.equals(surname, other.getSurname())) {
+ return false;
+ }
+ if (!Objects.equals(givenName, other.getGivenName())) {
+ return false;
+ }
+ if (!Objects.equals(prefix, other.getPrefix())) {
+ return false;
+ }
+ if (!Objects.equals(suffix, other.getSuffix())) {
+ return false;
+ }
+ return Objects.equals(birthdate, other.getBirthdate());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+
+ return obj instanceof Person;
+ }
+
+ @Override
+ public String toString(final String data) {
+
+ return super.toString(String.format(
+ "surname = \"%s\", "
+ + "givenName = \"%s\", "
+ + "prefix = \"%s\", "
+ + "suffix = \"%s\", "
+ + "birthdate = %s%s",
+ surname,
+ givenName,
+ prefix,
+ suffix,
+ Objects.toString(birthdate),
+ data));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/assets/PostalAddress.java b/ccm-cms/src/main/java/org/librecms/assets/PostalAddress.java
new file mode 100644
index 000000000..ffee8f118
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/assets/PostalAddress.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.assets;
+
+import org.librecms.contentsection.Asset;
+
+import java.util.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * A reuable postal address.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "POSTAL_ADDRESSES", schema = DB_SCHEMA)
+public class PostalAddress extends Asset {
+
+ private static final long serialVersionUID = 1L;
+
+ @Column(name = "ADDRESS", length = 2048)
+ private String address;
+
+ @Column(name = "POSTAL_CODE", length = 255)
+ private String postalCode;
+
+ @Column(name = "CITY", length = 512)
+ private String city;
+
+ @Column(name = "ADDRESS_STATE", length = 255)
+ private String state;
+
+ @Column(name = "ISO_COUNTRY_CODE", length = 10)
+ private String isoCountryCode;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(final String address) {
+ this.address = address;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(final String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(final String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(final String state) {
+ this.state = state;
+ }
+
+ public String getIsoCountryCode() {
+ return isoCountryCode;
+ }
+
+ public void setIsoCountryCode(final String isoCountryCode) {
+ this.isoCountryCode = isoCountryCode;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 67 * hash + Objects.hashCode(address);
+ hash = 67 * hash + Objects.hashCode(postalCode);
+ hash = 67 * hash + Objects.hashCode(city);
+ hash = 67 * hash + Objects.hashCode(state);
+ hash = 67 * hash + Objects.hashCode(isoCountryCode);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+
+ if (!(obj instanceof PostalAddress)) {
+ return false;
+ }
+ final PostalAddress other = (PostalAddress) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (!Objects.equals(address, other.getAddress())) {
+ return false;
+ }
+ if (!Objects.equals(postalCode, other.getPostalCode())) {
+ return false;
+ }
+ if (!Objects.equals(city, other.getCity())) {
+ return false;
+ }
+ if (!Objects.equals(state, other.getState())) {
+ return false;
+ }
+ return Objects.equals(isoCountryCode, other.getIsoCountryCode());
+ }
+
+ @Override
+ public String toString(final String data) {
+
+ return super.toString(String.format(
+ "address = \"%s\", "
+ + "postalCode = \"%s\", "
+ + "city = \"%s\", "
+ + "state = \"%s\", "
+ + "isoCountryCode = \"%s\"%s",
+ address,
+ postalCode,
+ city,
+ state,
+ isoCountryCode,
+ data));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/AssetManager.java b/ccm-cms/src/main/java/org/librecms/contentsection/AssetManager.java
index 9c57ce2ed..a61f4727f 100644
--- a/ccm-cms/src/main/java/org/librecms/contentsection/AssetManager.java
+++ b/ccm-cms/src/main/java/org/librecms/contentsection/AssetManager.java
@@ -26,7 +26,6 @@ import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
-import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.apache.logging.log4j.LogManager;
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_20__persons_orga_assets.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_20__persons_orga_assets.sql
new file mode 100644
index 000000000..9f6948833
--- /dev/null
+++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_20__persons_orga_assets.sql
@@ -0,0 +1,70 @@
+create table CONTACT_ENTRIES (
+ CONTACT_ENTRY_ID bigint not null,
+ ENTRY_KEY varchar(255) not null,
+ ENTRY_ORDER bigint,
+ ENTRY_VALUE varchar(4096),
+ CONTACTABLE_ID bigint,
+ primary key (CONTACT_ENTRY_ID)
+);
+
+create table CONTACTABLE_ENTITIES (
+ OBJECT_ID bigint not null,
+ POSTAL_ADDRESS_ID bigint,
+ primary key (OBJECT_ID)
+);
+
+create table ORGANIZATIONS (
+ NAME varchar(1024),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+);
+
+create table PERSONS (
+ BIRTHDATA date,
+ GIVEN_NAME varchar(255),
+ NAME_PREFIX varchar(255),
+ SUFFIX varchar(255),
+ SURNAME varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+);
+
+create table POSTAL_ADDRESSES (
+ ADDRESS varchar(2048),
+ CITY varchar(512),
+ ISO_COUNTRY_CODE varchar(10),
+ POSTAL_CODE varchar(255),
+ ADDRESS_STATE varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+);
+
+alter table CONTACT_ENTRIES
+ add constraint FKfm16ni25r5iscfcyqhlyo4y24
+ foreign key (CONTACTABLE_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table CONTACTABLE_ENTITY
+ add constraint FKn7nb0chctw8ih05kguf2s4jh0
+ foreign key (POSTAL_ADDRESS_ID)
+ references POSTAL_ADDRESSES;
+
+alter table CONTACTABLE_ENTITY
+ add constraint FK37gvl3x07envs4u4lwustuyge
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
+alter table ORGANIZATIONS
+ add constraint FKjjcnjs0eecrla6eqq8fes8o86
+ foreign key (OBJECT_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table PERSONS
+ add constraint FK3i2r1w7qc1ofdn4jlbak7vkpu
+ foreign key (OBJECT_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table POSTAL_ADDRESSES
+ add constraint FK4vajjjjo8ro0wns58t8f3i782
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
\ No newline at end of file
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_20__persons_orga_assets.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_20__persons_orga_assets.sql
new file mode 100644
index 000000000..7e06caeef
--- /dev/null
+++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_20__persons_orga_assets.sql
@@ -0,0 +1,70 @@
+create table CCM_CMS.CONTACT_ENTRIES (
+ CONTACT_ENTRY_ID int8 not null,
+ ENTRY_KEY varchar(255) not null,
+ ENTRY_ORDER int8,
+ ENTRY_VALUE varchar(4096),
+ CONTACTABLE_ID int8,
+ primary key (CONTACT_ENTRY_ID)
+);
+
+create table CCM_CMS.CONTACTABLE_ENTITIES (
+ OBJECT_ID int8 not null,
+ POSTAL_ADDRESS_ID int8,
+ primary key (OBJECT_ID)
+);
+
+create table CCM_CMS.ORGANIZATIONS (
+ NAME varchar(1024),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+);
+
+create table CCM_CMS.PERSONS (
+ BIRTHDATA date,
+ GIVEN_NAME varchar(255),
+ NAME_PREFIX varchar(255),
+ SUFFIX varchar(255),
+ SURNAME varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+);
+
+create table CCM_CMS.POSTAL_ADDRESSES (
+ ADDRESS varchar(2048),
+ CITY varchar(512),
+ ISO_COUNTRY_CODE varchar(10),
+ POSTAL_CODE varchar(255),
+ ADDRESS_STATE varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+);
+
+alter table CCM_CMS.CONTACT_ENTRIES
+ add constraint FKfm16ni25r5iscfcyqhlyo4y24
+ foreign key (CONTACTABLE_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table CCM_CMS.CONTACTABLE_ENTITY
+ add constraint FKn7nb0chctw8ih05kguf2s4jh0
+ foreign key (POSTAL_ADDRESS_ID)
+ references POSTAL_ADDRESSES;
+
+alter table CCM_CMS.CONTACTABLE_ENTITY
+ add constraint FK37gvl3x07envs4u4lwustuyge
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
+alter table CCM_CMS.ORGANIZATIONS
+ add constraint FKjjcnjs0eecrla6eqq8fes8o86
+ foreign key (OBJECT_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table CCM_CMS.PERSONS
+ add constraint FK3i2r1w7qc1ofdn4jlbak7vkpu
+ foreign key (OBJECT_ID)
+ references CONTACTABLE_ENTITY;
+
+alter table CCM_CMS.POSTAL_ADDRESSES
+ add constraint FK4vajjjjo8ro0wns58t8f3i782
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
\ No newline at end of file
diff --git a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/002_create_ccm_cms_tables.sql b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/002_create_ccm_cms_tables.sql
index 38fa156d6..5037967b8 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/002_create_ccm_cms_tables.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/002_create_ccm_cms_tables.sql
@@ -221,6 +221,21 @@
primary key (COMPONENT_MODEL_ID)
);
+ create table CCM_CMS.CONTACT_ENTRIES (
+ CONTACT_ENTRY_ID bigint not null,
+ ENTRY_KEY varchar(255) not null,
+ ENTRY_ORDER bigint,
+ ENTRY_VALUE varchar(4096),
+ CONTACTABLE_ID bigint,
+ primary key (CONTACT_ENTRY_ID)
+ );
+
+ create table CCM_CMS.CONTACTABLE_ENTITIES (
+ OBJECT_ID bigint not null,
+ POSTAL_ADDRESS_ID bigint,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.CONTENT_ITEM_COMPONENTS (
MODE varchar(255),
COMPONENT_MODEL_ID bigint not null,
@@ -805,6 +820,12 @@
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
+ create table CCM_CMS.ORGANIZATIONS (
+ NAME varchar(1024),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
PAGE_ID bigint not null,
INDEX_PAGE_TEMPLATE varchar(255),
@@ -827,6 +848,26 @@
primary key (OBJECT_ID)
);
+ create table CCM_CMS.PERSONS (
+ BIRTHDATA date,
+ GIVEN_NAME varchar(255),
+ NAME_PREFIX varchar(255),
+ SUFFIX varchar(255),
+ SURNAME varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+ );
+
+ create table CCM_CMS.POSTAL_ADDRESSES (
+ ADDRESS varchar(2048),
+ CITY varchar(512),
+ ISO_COUNTRY_CODE varchar(10),
+ POSTAL_CODE varchar(255),
+ ADDRESS_STATE varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.RELATED_LINKS (
OBJECT_ID bigint not null,
BOOKMARK_ID bigint,
@@ -1444,10 +1485,10 @@
CONFIGURATION_CLASS varchar(512) not null,
NAME varchar(512) not null,
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
+ SETTING_VALUE_STRING varchar(1024),
+ SETTING_VALUE_LONG bigint,
SETTING_VALUE_DOUBLE double,
SETTING_VALUE_BOOLEAN boolean,
- SETTING_VALUE_LONG bigint,
- SETTING_VALUE_STRING varchar(1024),
primary key (SETTING_ID)
);
@@ -1917,6 +1958,21 @@ create sequence hibernate_sequence start with 1 increment by 1;
foreign key (COMPONENT_MODEL_ID)
references CCM_CORE.PAGE_MODEL_COMPONENT_MODELS;
+ alter table CCM_CMS.CONTACT_ENTRIES
+ add constraint FKljrrfco44damal9eaqrnfam0m
+ foreign key (CONTACTABLE_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
+ alter table CCM_CMS.CONTACTABLE_ENTITIES
+ add constraint FKqefwowr9adclj3xvpfje9rddr
+ foreign key (POSTAL_ADDRESS_ID)
+ references CCM_CMS.POSTAL_ADDRESSES;
+
+ alter table CCM_CMS.CONTACTABLE_ENTITIES
+ add constraint FKhdwlhf3jp8wf5wxjkoynrcspj
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
alter table CCM_CMS.CONTENT_ITEM_COMPONENTS
add constraint FKp83o82kxo2ipa0xo03wxp4dcr
foreign key (COMPONENT_MODEL_ID)
@@ -2447,6 +2503,11 @@ create sequence hibernate_sequence start with 1 increment by 1;
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
+ alter table CCM_CMS.ORGANIZATIONS
+ add constraint FK77ig0to48xrlfx8qsc0vlfsp6
+ foreign key (OBJECT_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
foreign key (PAGE_ID)
@@ -2477,6 +2538,16 @@ create sequence hibernate_sequence start with 1 increment by 1;
foreign key (OBJECT_ID)
references CCM_CORE.SITE_AWARE_APPLICATIONS;
+ alter table CCM_CMS.PERSONS
+ add constraint FKiv4ydysjekfx64pkb5v4vd9yj
+ foreign key (OBJECT_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
+ alter table CCM_CMS.POSTAL_ADDRESSES
+ add constraint FK4vajjjjo8ro0wns58t8f3i782
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
alter table CCM_CMS.RELATED_LINKS
add constraint FKb517dnfj56oby2s34jp1omuim
foreign key (BOOKMARK_ID)
diff --git a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/999_cleanup.sql b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/999_cleanup.sql
index 0cf352a13..428ccfaef 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/999_cleanup.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/999_cleanup.sql
@@ -18,6 +18,16 @@ DELETE FROM ccm_cms.binary_assets_aud;
DELETE FROM ccm_cms.binary_assets;
+DELETE FROM ccm_cms.contact_entries;
+
+DELETE FROM ccm_cms.organizations;
+
+DELETE FROM ccm_cms.persons;
+
+DELETE FROM ccm_cms.contactable_entities;
+
+DELETE FROM ccm_cms.postal_addresses;
+
DELETE FROM ccm_cms.asset_titles_aud;
DELETE FROM ccm_cms.asset_titles;
diff --git a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/002_create_ccm_cms_tables.sql b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/002_create_ccm_cms_tables.sql
index cd19e1a32..1c536fb62 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/002_create_ccm_cms_tables.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/002_create_ccm_cms_tables.sql
@@ -221,6 +221,21 @@
primary key (COMPONENT_MODEL_ID)
);
+ create table CCM_CMS.CONTACT_ENTRIES (
+ CONTACT_ENTRY_ID int8 not null,
+ ENTRY_KEY varchar(255) not null,
+ ENTRY_ORDER int8,
+ ENTRY_VALUE varchar(4096),
+ CONTACTABLE_ID int8,
+ primary key (CONTACT_ENTRY_ID)
+ );
+
+ create table CCM_CMS.CONTACTABLE_ENTITIES (
+ OBJECT_ID int8 not null,
+ POSTAL_ADDRESS_ID int8,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.CONTENT_ITEM_COMPONENTS (
MODE varchar(255),
COMPONENT_MODEL_ID int8 not null,
@@ -805,6 +820,12 @@
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
+ create table CCM_CMS.ORGANIZATIONS (
+ NAME varchar(1024),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
PAGE_ID int8 not null,
INDEX_PAGE_TEMPLATE varchar(255),
@@ -827,6 +848,26 @@
primary key (OBJECT_ID)
);
+ create table CCM_CMS.PERSONS (
+ BIRTHDATA date,
+ GIVEN_NAME varchar(255),
+ NAME_PREFIX varchar(255),
+ SUFFIX varchar(255),
+ SURNAME varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+ );
+
+ create table CCM_CMS.POSTAL_ADDRESSES (
+ ADDRESS varchar(2048),
+ CITY varchar(512),
+ ISO_COUNTRY_CODE varchar(10),
+ POSTAL_CODE varchar(255),
+ ADDRESS_STATE varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.RELATED_LINKS (
OBJECT_ID int8 not null,
BOOKMARK_ID int8,
@@ -1444,10 +1485,10 @@
CONFIGURATION_CLASS varchar(512) not null,
NAME varchar(512) not null,
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
+ SETTING_VALUE_STRING varchar(1024),
+ SETTING_VALUE_LONG int8,
SETTING_VALUE_DOUBLE float8,
SETTING_VALUE_BOOLEAN boolean,
- SETTING_VALUE_LONG int8,
- SETTING_VALUE_STRING varchar(1024),
primary key (SETTING_ID)
);
@@ -1917,6 +1958,21 @@ create sequence hibernate_sequence start 1 increment 1;
foreign key (COMPONENT_MODEL_ID)
references CCM_CORE.PAGE_MODEL_COMPONENT_MODELS;
+ alter table CCM_CMS.CONTACT_ENTRIES
+ add constraint FKljrrfco44damal9eaqrnfam0m
+ foreign key (CONTACTABLE_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
+ alter table CCM_CMS.CONTACTABLE_ENTITIES
+ add constraint FKqefwowr9adclj3xvpfje9rddr
+ foreign key (POSTAL_ADDRESS_ID)
+ references CCM_CMS.POSTAL_ADDRESSES;
+
+ alter table CCM_CMS.CONTACTABLE_ENTITIES
+ add constraint FKhdwlhf3jp8wf5wxjkoynrcspj
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
alter table CCM_CMS.CONTENT_ITEM_COMPONENTS
add constraint FKp83o82kxo2ipa0xo03wxp4dcr
foreign key (COMPONENT_MODEL_ID)
@@ -2447,6 +2503,11 @@ create sequence hibernate_sequence start 1 increment 1;
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
+ alter table CCM_CMS.ORGANIZATIONS
+ add constraint FK77ig0to48xrlfx8qsc0vlfsp6
+ foreign key (OBJECT_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
foreign key (PAGE_ID)
@@ -2477,6 +2538,16 @@ create sequence hibernate_sequence start 1 increment 1;
foreign key (OBJECT_ID)
references CCM_CORE.SITE_AWARE_APPLICATIONS;
+ alter table CCM_CMS.PERSONS
+ add constraint FKiv4ydysjekfx64pkb5v4vd9yj
+ foreign key (OBJECT_ID)
+ references CCM_CMS.CONTACTABLE_ENTITIES;
+
+ alter table CCM_CMS.POSTAL_ADDRESSES
+ add constraint FK4vajjjjo8ro0wns58t8f3i782
+ foreign key (OBJECT_ID)
+ references CCM_CMS.ASSETS;
+
alter table CCM_CMS.RELATED_LINKS
add constraint FKb517dnfj56oby2s34jp1omuim
foreign key (BOOKMARK_ID)
diff --git a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/999_cleanup.sql b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/999_cleanup.sql
index 0cf352a13..428ccfaef 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/999_cleanup.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/999_cleanup.sql
@@ -18,6 +18,16 @@ DELETE FROM ccm_cms.binary_assets_aud;
DELETE FROM ccm_cms.binary_assets;
+DELETE FROM ccm_cms.contact_entries;
+
+DELETE FROM ccm_cms.organizations;
+
+DELETE FROM ccm_cms.persons;
+
+DELETE FROM ccm_cms.contactable_entities;
+
+DELETE FROM ccm_cms.postal_addresses;
+
DELETE FROM ccm_cms.asset_titles_aud;
DELETE FROM ccm_cms.asset_titles;