-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
355 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,3 +31,7 @@ Example 5 | |
|
||
Aggregate entity with simple audit. | ||
|
||
Example 6 | ||
--------- | ||
|
||
Custom type for CLOB (e.g: JSON). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package design.domain.example6; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
import javax.persistence.Version; | ||
|
||
import org.hibernate.annotations.Columns; | ||
|
||
import design.domain.example6.clob.ClobHolder; | ||
|
||
@Entity | ||
public class Example6 { | ||
|
||
@Id | ||
private String id; | ||
|
||
@Version | ||
private Integer version; | ||
|
||
@Columns(columns = { @Column(name = "value_object_json_class"), @Column(name = "value_object_json_value") }) | ||
private ClobHolder<Example6Clob> clobHolder = ClobHolder.absent(); | ||
|
||
Example6() { | ||
} | ||
|
||
public Example6(String id, Example6Clob valueObject) { | ||
this.id = requireNonNull(id); | ||
this.clobHolder = ClobHolder.of(valueObject); | ||
} | ||
|
||
public String getId() { | ||
return id; | ||
} | ||
|
||
public Integer getVersion() { | ||
return version; | ||
} | ||
|
||
public Example6Clob getValueObject() { | ||
return clobHolder.getValue(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package design.domain.example6; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import javax.persistence.Embeddable; | ||
|
||
import ddd.domain.AbstractValueObject; | ||
|
||
@Embeddable | ||
public class Example6Clob extends AbstractValueObject { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
private String name; | ||
|
||
Example6Clob() { | ||
} | ||
|
||
public Example6Clob(String name) { | ||
this.name = requireNonNull(name); | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package design.domain.example6; | ||
|
||
import ddd.domain.Repository; | ||
|
||
public interface Example6Repository extends Repository<Example6, String> { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package design.domain.example6.clob; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import java.io.Serializable; | ||
|
||
public class ClobHolder<T> implements Serializable { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
private T value; | ||
|
||
ClobHolder() { | ||
} | ||
|
||
public static <T> ClobHolder<T> of(T value) { | ||
ClobHolder<T> jsonHolder = new ClobHolder<T>(); | ||
jsonHolder.value = requireNonNull(value); | ||
return jsonHolder; | ||
} | ||
|
||
public static <T> ClobHolder<T> absent() { | ||
return new ClobHolder<T>(); | ||
} | ||
|
||
public T getValue() { | ||
return value; | ||
} | ||
|
||
public boolean hasValue() { | ||
return value != null; | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/design/domain/example6/clob/ClobSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package design.domain.example6.clob; | ||
|
||
public interface ClobSerializer { | ||
|
||
String toClob(Object object); | ||
|
||
Object fromClob(String clob, String type); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/main/java/design/infrastructure/jpa/repositories/JpaExample6Repository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package design.infrastructure.jpa.repositories; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import ddd.infrastructure.jpa.AbstractJpaRepository; | ||
import design.domain.example6.Example6; | ||
import design.domain.example6.Example6Repository; | ||
|
||
@Component | ||
public class JpaExample6Repository extends AbstractJpaRepository<Example6, String> implements Example6Repository { | ||
} |
56 changes: 56 additions & 0 deletions
56
src/main/java/design/infrastructure/jpa/types/AbstractCustomType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package design.infrastructure.jpa.types; | ||
|
||
import java.io.Serializable; | ||
import java.util.Objects; | ||
|
||
import org.hibernate.HibernateException; | ||
import org.hibernate.engine.spi.SessionImplementor; | ||
|
||
public abstract class AbstractCustomType { | ||
|
||
public void setPropertyValue(Object component, int propertyIndex, Object value) throws HibernateException { | ||
throw new HibernateException("Called setPropertyValue on an immutable type {" + component.getClass() + "}"); | ||
} | ||
|
||
public boolean equals(Object x, Object y) throws HibernateException { | ||
return Objects.equals(x, y); | ||
} | ||
|
||
public int hashCode(Object x) throws HibernateException { | ||
return Objects.hashCode(x); | ||
} | ||
|
||
public Object deepCopy(Object value) throws HibernateException { | ||
return value; | ||
} | ||
|
||
public boolean isMutable() { | ||
return false; | ||
} | ||
|
||
public Serializable disassemble(Object value) throws HibernateException { | ||
return (Serializable) value; | ||
} | ||
|
||
public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException { | ||
return (Serializable) value; | ||
} | ||
|
||
public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException { | ||
return cached; | ||
} | ||
|
||
public Object assemble(Serializable cached, Object value) throws HibernateException { | ||
return cached; | ||
} | ||
|
||
public Object replace(Object original, Object target, SessionImplementor session, Object owner) | ||
throws HibernateException { | ||
return original; | ||
} | ||
|
||
public Object replace(Object original, Object target, Object owner) throws HibernateException { | ||
return original; | ||
} | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
src/main/java/design/infrastructure/jpa/types/ClobHolderType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package design.infrastructure.jpa.types; | ||
|
||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
|
||
import org.hibernate.HibernateException; | ||
import org.hibernate.engine.spi.SessionImplementor; | ||
import org.hibernate.type.StringType; | ||
import org.hibernate.type.TextType; | ||
import org.hibernate.type.Type; | ||
import org.hibernate.usertype.CompositeUserType; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
import design.domain.example6.clob.ClobHolder; | ||
import design.domain.example6.clob.ClobSerializer; | ||
|
||
@Component | ||
public class ClobHolderType extends AbstractCustomType implements CompositeUserType { | ||
|
||
private static ClobSerializer clobSerializer; | ||
|
||
@Autowired | ||
void setJsonSerializationService(ClobSerializer clobSerializer) { | ||
ClobHolderType.clobSerializer = clobSerializer; | ||
} | ||
|
||
@Override | ||
public String[] getPropertyNames() { | ||
return new String[] { "type", "data" }; | ||
} | ||
|
||
@Override | ||
public Type[] getPropertyTypes() { | ||
return new Type[] { StringType.INSTANCE, TextType.INSTANCE }; | ||
} | ||
|
||
@SuppressWarnings("rawtypes") | ||
@Override | ||
public Class<ClobHolder> returnedClass() { | ||
return ClobHolder.class; | ||
} | ||
|
||
@SuppressWarnings("rawtypes") | ||
@Override | ||
public Object getPropertyValue(Object component, int propertyIndex) throws HibernateException { | ||
if (component == null) { | ||
return null; | ||
} | ||
|
||
ClobHolder clobHolder = (ClobHolder) component; | ||
if (!clobHolder.hasValue()) { | ||
return null; | ||
} | ||
|
||
switch (propertyIndex) { | ||
case 0: | ||
return clobHolder.getValue().getClass().getName(); | ||
case 1: | ||
return clobSerializer.toClob(clobHolder.getValue()); | ||
default: | ||
throw new HibernateException("Invalid property index [" + propertyIndex + "]"); | ||
} | ||
} | ||
|
||
@Override | ||
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) | ||
throws HibernateException, SQLException { | ||
|
||
String type = StringType.INSTANCE.nullSafeGet(rs, names[0], session); | ||
String data = TextType.INSTANCE.nullSafeGet(rs, names[1], session); | ||
|
||
if (type == null && data == null) { | ||
return null; | ||
} else { | ||
Object json = clobSerializer.fromClob(data, type); | ||
return ClobHolder.of(json); | ||
} | ||
} | ||
|
||
@SuppressWarnings("rawtypes") | ||
@Override | ||
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) | ||
throws HibernateException, SQLException { | ||
ClobHolder clobHolder = (ClobHolder) value; | ||
|
||
if (clobHolder != null && clobHolder.getValue() != null) { | ||
StringType.INSTANCE.set(st, clobHolder.getValue().getClass().getName(), index, session); | ||
TextType.INSTANCE.set(st, clobSerializer.toClob(clobHolder.getValue()), index + 1, session); | ||
} else { | ||
StringType.INSTANCE.set(st, null, index, session); | ||
TextType.INSTANCE.set(st, null, index + 1, session); | ||
} | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/design/infrastructure/jpa/types/CustomTypes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package design.infrastructure.jpa.types; | ||
|
||
import javax.persistence.MappedSuperclass; | ||
|
||
import org.hibernate.annotations.TypeDef; | ||
import org.hibernate.annotations.TypeDefs; | ||
|
||
import design.domain.example6.clob.ClobHolder; | ||
|
||
@MappedSuperclass | ||
@TypeDefs({ @TypeDef(defaultForType = ClobHolder.class, typeClass = ClobHolderType.class) }) | ||
public class CustomTypes { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.