Skip to content

Commit

Permalink
#628 Map JSON types with Hibernate 6's native JSON mapping (only on P…
Browse files Browse the repository at this point in the history
…ostgres, untested)
  • Loading branch information
alessiostalla committed Jan 6, 2023
1 parent a954252 commit 9157410
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
import com.manydesigns.portofino.database.model.Column;
import com.manydesigns.portofino.database.model.ConnectionProvider;
import com.manydesigns.portofino.database.model.platforms.AbstractDatabasePlatform;
import com.manydesigns.portofino.model.Annotation;
import com.manydesigns.portofino.persistence.hibernate.ColumnParameterType;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.usertype.DynamicParameterizedType;

import java.math.BigDecimal;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
Expand Down Expand Up @@ -73,21 +77,15 @@ public boolean isApplicable(ConnectionProvider connectionProvider) {
}

@Override
public TypeDescriptor getDatabaseSpecificType(Column column) {
public List<Annotation> getAdditionalAnnotations(Column column) {
if ("JSONB".equalsIgnoreCase(column.getColumnType())) {
// TODO Hibernate 6 should support JSON mapping na
Properties typeParams = new Properties();
if(column.getActualJavaType() == Map.class) {
typeParams.put(DynamicParameterizedType.PARAMETER_TYPE, new ColumnParameterType(column, Map.class));
return new TypeDescriptor("com.marvinformatics.hibernate.json.JsonUserType", typeParams);
} else if(column.getActualJavaType() == List.class) {
typeParams.put(DynamicParameterizedType.PARAMETER_TYPE, new ColumnParameterType(column, Object.class));
return new TypeDescriptor("com.marvinformatics.hibernate.json.JsonListUserType", typeParams);
} else {
logger.warn("Unsupported column data type: " + column.getActualJavaType());
}
Annotation annotation = new Annotation();
annotation.setType(JdbcTypeCode.class.getName());
annotation.setPropertyValue("value", SqlTypes.JSON + "");
return Collections.singletonList(annotation);
} else {
return super.getAdditionalAnnotations(column);
}
return super.getDatabaseSpecificType(column);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<fop.version>2.8</fop.version>
<groovy.version>4.0.3</groovy.version>
<guava.version>31.0.1-jre</guava.version>
<hibernate.version>6.1.4.Final</hibernate.version>
<hibernate.version>6.1.6.Final</hibernate.version>
<jackson.version>2.13.4</jackson.version>
<jackson.databind.version>2.13.4.2</jackson.databind.version>
<javassist.version>3.24.0-GA</javassist.version> <!-- Hibernate 5 depended on this version, Jersey depends on 3.18.1-GA, Swagger depends on 3.22.0-GA -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,12 @@ public class Column implements ModelObject, Annotated, Named, Unmarshallable {
public static final String copyright =
"Copyright (C) 2005-2021 ManyDesigns srl";

//**************************************************************************
// Fields (physical JDBC)
//**************************************************************************

protected Table table;

//**************************************************************************
// Fields (logical)
//**************************************************************************

protected String javaType; // Legacy XML-only property
protected EAttribute property;
protected Annotation columnInfo;
protected List<Annotation> annotations = new ArrayList<>();

//**************************************************************************
// Fields for wire-up
//**************************************************************************

protected String propertyName;
protected String propertyName; // Legacy XML-only property

public static final Logger logger = LoggerFactory.getLogger(Column.class);

Expand Down Expand Up @@ -121,13 +107,15 @@ public void init(Object context, Configuration configuration) {
throw new IllegalStateException("columnName must not be null");
}

if (StringUtils.isEmpty(propertyName)) {
String initialName = DatabaseLogic.normalizeName(getColumnName());
if(!initialName.equals(property.getName())) {
property.setName(DatabaseLogic.getUniquePropertyName(table, initialName));
if (property.getName() == null) {
if (StringUtils.isEmpty(propertyName)) {
String initialName = DatabaseLogic.normalizeName(getColumnName());
if (!initialName.equals(property.getName())) {
property.setName(DatabaseLogic.getUniquePropertyName(table, initialName));
}
} else {
property.setName(DatabaseLogic.getUniquePropertyName(table, propertyName));
}
} else {
property.setName(propertyName); //AS do not normalize (can be mixed-case Java properties)
}
// Re-set the column name so that if it's equal to the property name it's not saved in the annotation
setColumnName(getColumnName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.manydesigns.portofino.database.model.Column;
import com.manydesigns.portofino.database.model.ConnectionProvider;
import com.manydesigns.portofino.database.model.Type;
import com.manydesigns.portofino.model.Annotation;
import org.apache.commons.dbutils.DbUtils;
import org.jetbrains.annotations.Nullable;
import org.joda.time.DateTime;
Expand All @@ -38,6 +39,7 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/*
Expand Down Expand Up @@ -123,6 +125,11 @@ public TypeDescriptor getDatabaseSpecificType(Column column) {
return null;
}

@Override
public List<Annotation> getAdditionalAnnotations(Column column) {
return Collections.emptyList();
}

public String getHibernateDialect() {
return hibernateDialect;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.manydesigns.portofino.database.model.Column;
import com.manydesigns.portofino.database.model.ConnectionProvider;
import com.manydesigns.portofino.database.model.Type;
import com.manydesigns.portofino.model.Annotation;
import org.jetbrains.annotations.Nullable;

import java.sql.DatabaseMetaData;
Expand Down Expand Up @@ -62,6 +63,8 @@ public interface DatabasePlatform extends TypeProvider {

TypeDescriptor getDatabaseSpecificType(Column column);

List<Annotation> getAdditionalAnnotations(Column column);

void test();
boolean isApplicable(ConnectionProvider connectionProvider);
void shutdown(ConnectionProvider connectionProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.VFS;
import org.hibernate.MappingException;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Immutable;
import org.hibernate.boot.Metadata;
Expand All @@ -48,7 +47,6 @@
import jakarta.persistence.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
Expand Down Expand Up @@ -570,7 +568,8 @@ protected void setupColumns(Table table, CtClass cc, ConstPool constPool) throws
}
}

setupColumnType(column, fieldAnnotations, constPool);
setupColumnTypeAnnotation(column, fieldAnnotations, constPool);
setupColumnCustomAnnotations(column, fieldAnnotations, constPool);

column.getAnnotations().forEach(ann -> {
Class<?> annotationClass = ann.getJavaAnnotationClass();
Expand Down Expand Up @@ -668,7 +667,7 @@ protected Annotation makeGeneratedValueAnnotation(GenerationType identity, Const
return annotation;
}

protected void setupColumnType(Column column, AnnotationsAttribute fieldAnnotations, ConstPool constPool) {
protected void setupColumnTypeAnnotation(Column column, AnnotationsAttribute fieldAnnotations, ConstPool constPool) {
Annotation annotation;
if(Boolean.class.equals(column.getActualJavaType())) {
if(column.getJdbcType() == Types.CHAR || column.getJdbcType() == Types.VARCHAR) {
Expand Down Expand Up @@ -702,6 +701,18 @@ protected void setupColumnType(Column column, AnnotationsAttribute fieldAnnotati
}
}

protected void setupColumnCustomAnnotations
(Column column, AnnotationsAttribute fieldAnnotations, ConstPool constPool) {
List<com.manydesigns.portofino.model.Annotation> annotations =
database.getConnectionProvider().getDatabasePlatform().getAdditionalAnnotations(column);
for (com.manydesigns.portofino.model.Annotation annotation : annotations) {
Annotation fieldAnn = convertAnnotation(constPool, annotation);
if (fieldAnn != null) {
fieldAnnotations.addAnnotation(fieldAnn);
}
}
}

public void mapRelationships(Table table) throws NotFoundException, CannotCompileException {
for(ForeignKey foreignKey : table.getForeignKeys()) {
if(checkValidFk(foreignKey)) {
Expand Down

0 comments on commit 9157410

Please sign in to comment.