mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-14 06:45:21 +00:00
Merge remote-tracking branch 'upstream/master'
# Conflicts: # ebean-bom/pom.xml # ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmt.java # ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/ddlgeneration/platform/DB2Ddl.java # ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.1.sql # ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/1.3.sql # ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations # ebean-test/src/test/java/org/tests/basic/TestMetaAnnotation.java # ebean-test/src/test/java/org/tests/model/basic/cache/TestCacheViaComplexNaturalKey3.java # tests/test-java16/pom.xml # tests/test-kotlin/pom.xml
This commit is contained in:
commit
090f3cddb8
56 files changed
+593
-597
No files matched your search
@@ -8,15 +8,15 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.util.UrlHelper;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
final class DScriptRunner implements ScriptRunner {
|
||||
|
||||
private static final String NEWLINE = "\n";
|
||||
@@ -30,8 +30,8 @@ final class DScriptRunner implements ScriptRunner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String path) {
|
||||
run(path, null);
|
||||
public void run(String resourcePath) {
|
||||
run(resourcePath, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,27 +49,42 @@ final class DScriptRunner implements ScriptRunner {
|
||||
run(resource, null, placeholderMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Path file) {
|
||||
run(file, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Path file, Map<String, String> placeholderMap) {
|
||||
requireNonNull(file);
|
||||
String scriptName = file.toFile().getName();
|
||||
String content = fileContent(file);
|
||||
runScript(content, scriptName, placeholderMap, false);
|
||||
}
|
||||
|
||||
private void run(URL resource, String scriptName, Map<String, String> placeholderMap) {
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("resource is null?");
|
||||
}
|
||||
requireNonNull(resource);
|
||||
if (scriptName == null) {
|
||||
scriptName = resource.getFile();
|
||||
}
|
||||
|
||||
String content = content(resource);
|
||||
runScript(content, scriptName, placeholderMap, false);
|
||||
}
|
||||
|
||||
private String content(URL resource) {
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("resource is null?");
|
||||
}
|
||||
|
||||
try (InputStream inputStream = UrlHelper.openNoCache(resource);
|
||||
Reader reader = IOUtils.newReader(inputStream)) {
|
||||
private String fileContent(Path file) {
|
||||
try (InputStream inputStream = new FileInputStream(file.toFile());
|
||||
Reader reader = IOUtils.newReader(inputStream)) {
|
||||
return readContent(reader);
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Failed to read script content", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String content(URL resource) {
|
||||
requireNonNull(resource);
|
||||
try (InputStream inputStream = UrlHelper.openNoCache(resource);
|
||||
Reader reader = IOUtils.newReader(inputStream)) {
|
||||
return readContent(reader);
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceException("Failed to read script content", e);
|
||||
}
|
||||
@@ -85,10 +100,9 @@ final class DScriptRunner implements ScriptRunner {
|
||||
*/
|
||||
private void runScript(String content, String scriptName, Map<String, String> placeholderMap, boolean useAutoCommit) {
|
||||
try {
|
||||
if (placeholderMap != null) {
|
||||
if (placeholderMap != null && !placeholderMap.isEmpty()) {
|
||||
content = ScriptTransform.build(null, placeholderMap).transform(content);
|
||||
}
|
||||
|
||||
try (Connection connection = obtainConnection()) {
|
||||
DdlRunner runner = new DdlRunner(useAutoCommit, scriptName, platformName);
|
||||
runner.runAll(content, connection);
|
||||
@@ -110,7 +124,6 @@ final class DScriptRunner implements ScriptRunner {
|
||||
}
|
||||
|
||||
private String readContent(Reader reader) throws IOException {
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
try (LineNumberReader lineReader = new LineNumberReader(reader)) {
|
||||
String line;
|
||||
|
||||
@@ -86,6 +86,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final ConcurrentHashMap<String, ElPropertyDeploy> elDeployCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Map<String,String>> pathMaps = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<String, SpiRawSql> namedRawSql;
|
||||
private final Map<String, String> namedQuery;
|
||||
private final boolean multiValueSupported;
|
||||
@@ -2775,6 +2777,22 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return draftableElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> pathMap(String prefix) {
|
||||
return pathMaps.computeIfAbsent(prefix, s -> {
|
||||
HashMap<String, String> m = new HashMap<>();
|
||||
for (STreePropertyAssocMany many : propsMany()) {
|
||||
String name = many.name();
|
||||
m.put(name, prefix + "." + name);
|
||||
}
|
||||
for (STreePropertyAssocOne one : propsOne()) {
|
||||
String name = one.name();
|
||||
m.put(name, prefix + "." + name);
|
||||
}
|
||||
return m.isEmpty() ? Collections.emptyMap() : m;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbeddedPath(String propertyPath) {
|
||||
ElPropertyDeploy elProp = elPropertyDeploy(propertyPath);
|
||||
|
||||
@@ -6,8 +6,6 @@ import io.ebeaninternal.api.SpiTransaction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -23,18 +21,12 @@ import java.util.List;
|
||||
*/
|
||||
public final class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
|
||||
/**
|
||||
* The underlying statement.
|
||||
*/
|
||||
private static final DB2GetKeys DB2_HACK = new DB2GetKeys();
|
||||
|
||||
private PreparedStatement pstmt;
|
||||
|
||||
/**
|
||||
* True if an insert that uses generated keys.
|
||||
*/
|
||||
private final boolean isGenKeys;
|
||||
|
||||
/**
|
||||
* The list of BatchPostExecute used to perform post processing.
|
||||
* The list of BatchPostExecute used to perform post-processing.
|
||||
*/
|
||||
private final List<BatchPostExecute> list = new ArrayList<>();
|
||||
private final String sql;
|
||||
@@ -44,18 +36,6 @@ public final class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
private int[] results;
|
||||
private List<InputStream> inputStreams;
|
||||
|
||||
private static Class<? extends PreparedStatement> DB2_PREPARED_STATEMENT;
|
||||
private static Method GET_DB_GENERATED_KEYS;
|
||||
|
||||
static {
|
||||
try {
|
||||
DB2_PREPARED_STATEMENT = (Class<? extends PreparedStatement>) Class.forName("com.ibm.db2.jcc.DB2PreparedStatement");
|
||||
GET_DB_GENERATED_KEYS = DB2_PREPARED_STATEMENT.getDeclaredMethod("getDBGeneratedKeys");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException cnf) {
|
||||
// NOP
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Create with a given statement.
|
||||
*/
|
||||
@@ -183,40 +163,15 @@ public final class BatchedPstmt implements SpiProfileTransactionEvent {
|
||||
}
|
||||
}
|
||||
|
||||
protected void getGeneratedKeys() throws SQLException {
|
||||
int index = 0;
|
||||
if (DB2_PREPARED_STATEMENT != null) {
|
||||
PreparedStatement db2Stmt = null;
|
||||
if (DB2_PREPARED_STATEMENT.isInstance(pstmt)) {
|
||||
db2Stmt = pstmt;
|
||||
} else if (pstmt.isWrapperFor(DB2_PREPARED_STATEMENT)) {
|
||||
db2Stmt = pstmt.unwrap(DB2_PREPARED_STATEMENT);
|
||||
}
|
||||
if (db2Stmt != null) {
|
||||
// WTF: https://stackoverflow.com/questions/41725492/how-to-get-auto-generated-keys-of-batch-insert-statement
|
||||
ResultSet[] result;
|
||||
try {
|
||||
result = (ResultSet[]) GET_DB_GENERATED_KEYS.invoke(db2Stmt);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new SQLException("Could not get generated keys for DB2", e);
|
||||
}
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
while (result[i].next()) {
|
||||
ResultSet rset = result[i];
|
||||
Object idValue = rset.getObject(1);
|
||||
list.get(index).setGeneratedKey(idValue);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
private void getGeneratedKeys() throws SQLException {
|
||||
if (DB2_HACK.getGeneratedKeys(pstmt, list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
try (ResultSet rset = pstmt.getGeneratedKeys()) {
|
||||
while (rset.next()) {
|
||||
Object idValue = rset.getObject(1);
|
||||
list.get(index).setGeneratedKey(idValue);
|
||||
index++;
|
||||
list.get(index++).setGeneratedKey(idValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package io.ebeaninternal.server.persist;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Horrible DB2 hack.
|
||||
*/
|
||||
final class DB2GetKeys {
|
||||
|
||||
private static Class<? extends PreparedStatement> DB2_PREPARED_STATEMENT;
|
||||
private static Method GET_DB_GENERATED_KEYS;
|
||||
|
||||
static {
|
||||
try {
|
||||
DB2_PREPARED_STATEMENT = (Class<? extends PreparedStatement>) Class.forName("com.ibm.db2.jcc.DB2PreparedStatement");
|
||||
GET_DB_GENERATED_KEYS = DB2_PREPARED_STATEMENT.getDeclaredMethod("getDBGeneratedKeys");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException cnf) {
|
||||
// NOP
|
||||
}
|
||||
}
|
||||
|
||||
static boolean getGeneratedKeys(PreparedStatement pstmt, List<BatchPostExecute> list) throws SQLException {
|
||||
if (DB2_PREPARED_STATEMENT != null) {
|
||||
PreparedStatement db2Stmt = null;
|
||||
if (DB2_PREPARED_STATEMENT.isInstance(pstmt)) {
|
||||
db2Stmt = pstmt;
|
||||
} else if (pstmt.isWrapperFor(DB2_PREPARED_STATEMENT)) {
|
||||
db2Stmt = pstmt.unwrap(DB2_PREPARED_STATEMENT);
|
||||
}
|
||||
if (db2Stmt != null) {
|
||||
// WTF: https://stackoverflow.com/questions/41725492/how-to-get-auto-generated-keys-of-batch-insert-statement
|
||||
ResultSet[] result;
|
||||
try {
|
||||
result = (ResultSet[]) GET_DB_GENERATED_KEYS.invoke(db2Stmt);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new SQLException("Could not get generated keys for DB2", e);
|
||||
}
|
||||
int index = 0;
|
||||
for (ResultSet resultSet : result) {
|
||||
while (resultSet.next()) {
|
||||
Object idValue = resultSet.getObject(1);
|
||||
list.get(index++).setGeneratedKey(idValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -581,20 +581,17 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
|
||||
@Override
|
||||
public void registerBeanInherit(BeanPropertyAssocOne<?> property, EntityBeanIntercept ebi) {
|
||||
String path = getPath(property.name());
|
||||
request.loadContext().register(path, ebi, property);
|
||||
request.loadContext().register(path(property.name()), ebi, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String path, EntityBeanIntercept ebi) {
|
||||
path = getPath(path);
|
||||
request.loadContext().register(path, ebi);
|
||||
request.loadContext().register(path(path), ebi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(BeanPropertyAssocMany<?> many, BeanCollection<?> bc) {
|
||||
String path = getPath(many.name());
|
||||
request.loadContext().register(path, many, bc);
|
||||
request.loadContext().register(path(many.name()), many, bc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -663,18 +660,14 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
return autoTuneProfiling && query.isUsageProfiling();
|
||||
}
|
||||
|
||||
private String getPath(String propertyName) {
|
||||
private String path(String propertyName) {
|
||||
if (currentPrefix == null) {
|
||||
return propertyName;
|
||||
} else if (propertyName == null) {
|
||||
return currentPrefix;
|
||||
}
|
||||
String path = currentPathMap.get(propertyName);
|
||||
if (path != null) {
|
||||
return path;
|
||||
} else {
|
||||
return currentPrefix + "." + propertyName;
|
||||
}
|
||||
return path != null ? path : currentPrefix + "." + propertyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,8 @@ import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Bean type interface for Sql query tree.
|
||||
*/
|
||||
@@ -136,4 +138,8 @@ public interface STreeType {
|
||||
*/
|
||||
void markAsDeleted(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return the "path map" to toMany or toOne properties using the given prefix.
|
||||
*/
|
||||
Map<String, String> pathMap(String prefix);
|
||||
}
|
||||
@@ -46,12 +46,12 @@ class SqlTreeLoadBean implements SqlTreeLoad {
|
||||
this.temporalMode = node.temporalMode;
|
||||
this.temporalVersions = node.temporalVersions;
|
||||
this.nodeBeanProp = node.nodeBeanProp;
|
||||
this.readId = node.readId;//!aggregationRoot && withId && desc.hasId();
|
||||
this.readId = node.readId;
|
||||
this.readIdNormal = readId && !temporalVersions;
|
||||
this.disableLazyLoad = node.disableLazyLoad;// disableLazyLoad || !readIdNormal || desc.isRawSqlBased();
|
||||
this.partialObject = node.partialObject;//props.isPartialObject();
|
||||
this.properties = node.properties;//props.getProps();
|
||||
this.pathMap = node.pathMap;//createPathMap(prefix, desc);
|
||||
this.disableLazyLoad = node.disableLazyLoad;
|
||||
this.partialObject = node.partialObject;
|
||||
this.properties = node.properties;
|
||||
this.pathMap = node.pathMap;
|
||||
this.children = node.createLoadChildren();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,13 @@ import java.util.*;
|
||||
class SqlTreeNodeBean implements SqlTreeNode {
|
||||
|
||||
private static final SqlTreeLoad[] NO_LOAD_CHILDREN = new SqlTreeLoad[0];
|
||||
private static final SqlTreeNode[] NO_CHILDREN = new SqlTreeNode[0];
|
||||
|
||||
final STreeType desc;
|
||||
final IdBinder idBinder;
|
||||
/**
|
||||
* The children which will be other SelectBean or SelectProxyBean.
|
||||
*/
|
||||
final SqlTreeNode[] children;
|
||||
final List<SqlTreeNode> children;
|
||||
/**
|
||||
* Set to true if this is a partial object fetch.
|
||||
*/
|
||||
@@ -94,8 +93,8 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
this.disableLazyLoad = disableLazyLoad || !readIdNormal || desc.isRawSqlBased();
|
||||
this.partialObject = props.isPartialObject();
|
||||
this.properties = props.getProps();
|
||||
this.children = myChildren == null ? NO_CHILDREN : myChildren.toArray(new SqlTreeNode[0]);
|
||||
pathMap = createPathMap(prefix, desc);
|
||||
this.children = myChildren == null ? Collections.emptyList() : myChildren;
|
||||
this.pathMap = createPathMap(prefix, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,10 +103,10 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
}
|
||||
|
||||
protected SqlTreeLoad[] createLoadChildren() {
|
||||
if (children.length == 0) {
|
||||
if (children.isEmpty()) {
|
||||
return NO_LOAD_CHILDREN;
|
||||
}
|
||||
List<SqlTreeLoad> loadChildren = new ArrayList<>(children.length);
|
||||
List<SqlTreeLoad> loadChildren = new ArrayList<>(children.size());
|
||||
for (SqlTreeNode child : children) {
|
||||
SqlTreeLoad load = child.createLoad();
|
||||
if (load != null) {
|
||||
@@ -119,24 +118,15 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
|
||||
@Override
|
||||
public final boolean isSingleProperty() {
|
||||
return properties != null && properties.length == 1 && children.length == 0;
|
||||
return properties != null && properties.length == 1 && children.isEmpty();
|
||||
}
|
||||
|
||||
private Map<String, String> createPathMap(String prefix, STreeType desc) {
|
||||
HashMap<String, String> m = new HashMap<>();
|
||||
for (STreePropertyAssocMany many : desc.propsMany()) {
|
||||
String name = many.name();
|
||||
m.put(name, getPath(prefix, name));
|
||||
}
|
||||
return m;
|
||||
return prefix == null ? Collections.emptyMap() : desc.pathMap(prefix);
|
||||
}
|
||||
|
||||
private String getPath(String prefix, String propertyName) {
|
||||
if (prefix == null) {
|
||||
return propertyName;
|
||||
} else {
|
||||
return prefix + "." + propertyName;
|
||||
}
|
||||
private String path(String prefix, String propertyName) {
|
||||
return prefix == null ? propertyName : prefix + "." + propertyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,7 +134,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
if (readId) {
|
||||
if (inheritInfo != null) {
|
||||
// discriminator column always proceeds id column
|
||||
selectChain.add(getPath(prefix, inheritInfo.getDiscriminatorColumn()));
|
||||
selectChain.add(path(prefix, inheritInfo.getDiscriminatorColumn()));
|
||||
}
|
||||
idBinder.buildRawSqlSelectChain(prefix, selectChain);
|
||||
}
|
||||
@@ -399,7 +389,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void unselectLobs() {
|
||||
|
||||
@@ -101,6 +101,7 @@ public final class DefaultTypeManager implements TypeManager {
|
||||
private final TypeJsonManager jsonManager;
|
||||
private final boolean offlineMigrationGeneration;
|
||||
private final EnumType defaultEnumType;
|
||||
private final DatabasePlatform databasePlatform;
|
||||
|
||||
// OPTIONAL ScalarTypes registered if Jackson/JsonNode is in the classpath
|
||||
|
||||
@@ -138,7 +139,8 @@ public final class DefaultTypeManager implements TypeManager {
|
||||
this.typeMap = new ConcurrentHashMap<>();
|
||||
this.nativeMap = new ConcurrentHashMap<>();
|
||||
this.logicalMap = new ConcurrentHashMap<>();
|
||||
this.postgres = isPostgres(config.getDatabasePlatform());
|
||||
this.databasePlatform = config.getDatabasePlatform();
|
||||
this.postgres = isPostgresCompatible(config.getDatabasePlatform());
|
||||
this.objectMapperPresent = config.getClassLoadConfig().isJacksonObjectMapperPresent();
|
||||
this.objectMapper = (objectMapperPresent) ? initObjectMapper(config) : null;
|
||||
this.jsonManager = (objectMapperPresent) ? new TypeJsonManager(postgres, objectMapper, config.getJsonMutationDetection()) : null;
|
||||
@@ -205,8 +207,13 @@ public final class DefaultTypeManager implements TypeManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPostgres(DatabasePlatform databasePlatform) {
|
||||
return databasePlatform.getPlatform().base() == Platform.POSTGRES;
|
||||
private boolean isPostgresCompatible(DatabasePlatform databasePlatform) {
|
||||
return databasePlatform.isPlatform(Platform.POSTGRES)
|
||||
|| databasePlatform.isPlatform(Platform.YUGABYTE);
|
||||
}
|
||||
|
||||
private boolean hstoreSupport() {
|
||||
return databasePlatform.isPlatform(Platform.POSTGRES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,7 +317,7 @@ public final class DefaultTypeManager implements TypeManager {
|
||||
|
||||
@Override
|
||||
public ScalarType<?> getDbMapScalarType() {
|
||||
return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR, false);
|
||||
return hstoreSupport() ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -748,7 +755,7 @@ public final class DefaultTypeManager implements TypeManager {
|
||||
jsonNodeVarchar = new ScalarTypeJsonNode.Varchar(mapper);
|
||||
jsonNodeJson = jsonNodeClob; // Default for non-Postgres databases
|
||||
jsonNodeJsonb = jsonNodeClob; // Default for non-Postgres databases
|
||||
if (isPostgres(config.getDatabasePlatform())) {
|
||||
if (postgres) {
|
||||
jsonNodeJson = new ScalarTypeJsonNodePostgres.JSON(mapper);
|
||||
jsonNodeJsonb = new ScalarTypeJsonNodePostgres.JSONB(mapper);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user