mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge remote-tracking branch 'ebean/master' into pr/bugfix/subquery_without_where
This commit is contained in:
@@ -90,14 +90,14 @@ public abstract class BaseTestCase {
|
||||
}
|
||||
|
||||
protected List<MetaTimedMetric> visitTimedMetrics() {
|
||||
return collectMetrics().getTimedMetrics();
|
||||
return collectMetrics().timedMetrics();
|
||||
}
|
||||
|
||||
protected List<MetaTimedMetric> sqlMetrics() {
|
||||
List<MetaTimedMetric> timedMetrics = visitTimedMetrics();
|
||||
|
||||
return timedMetrics.stream()
|
||||
.filter((it) -> it.getName().startsWith("sql.") || it.getName().startsWith("orm."))
|
||||
.filter((it) -> it.name().startsWith("sql.") || it.name().startsWith("orm."))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -191,13 +191,13 @@ public class DtoQuery2Test extends BaseTestCase {
|
||||
BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true);
|
||||
server().getMetaInfoManager().visitMetrics(basic);
|
||||
|
||||
List<MetaQueryMetric> stats = basic.getQueryMetrics();
|
||||
List<MetaQueryMetric> stats = basic.queryMetrics();
|
||||
assertThat(stats).hasSize(1);
|
||||
|
||||
MetaQueryMetric queryMetric = stats.get(0);
|
||||
assertThat(queryMetric.getLabel()).isEqualTo("basic");
|
||||
assertThat(queryMetric.getCount()).isEqualTo(3);
|
||||
assertThat(queryMetric.getName()).isEqualTo("dto.DCust_basic");
|
||||
assertThat(queryMetric.label()).isEqualTo("basic");
|
||||
assertThat(queryMetric.count()).isEqualTo(3);
|
||||
assertThat(queryMetric.name()).isEqualTo("dto.DCust_basic");
|
||||
|
||||
|
||||
server().findDto(DCust.class, "select c4.id, c4.name from o_customer c4 where lower(c4.name) = :name")
|
||||
@@ -207,7 +207,7 @@ public class DtoQuery2Test extends BaseTestCase {
|
||||
|
||||
BasicMetricVisitor metric2 = server().getMetaInfoManager().visitBasic();
|
||||
|
||||
stats = metric2.getQueryMetrics();
|
||||
stats = metric2.queryMetrics();
|
||||
assertThat(stats).hasSize(2);
|
||||
|
||||
log.info("stats " + stats);
|
||||
|
||||
@@ -27,12 +27,12 @@ public class DtoQueryFromOrmTest extends BaseTestCase {
|
||||
@AfterClass
|
||||
public static void reportStats() {
|
||||
ServerMetrics metrics = DB.getDefault().getMetaInfoManager().collectMetrics();
|
||||
for (MetaQueryMetric metric : metrics.getQueryMetrics()) {
|
||||
for (MetaQueryMetric metric : metrics.queryMetrics()) {
|
||||
System.out.println(metric);
|
||||
}
|
||||
|
||||
System.out.println("-- transaction metrics --");
|
||||
for (MetaTimedMetric metric : metrics.getTimedMetrics()) {
|
||||
for (MetaTimedMetric metric : metrics.timedMetrics()) {
|
||||
System.out.println(metric);
|
||||
}
|
||||
}
|
||||
@@ -59,15 +59,15 @@ public class DtoQueryFromOrmTest extends BaseTestCase {
|
||||
|
||||
ServerMetrics metrics = collectMetrics();
|
||||
|
||||
List<MetaQueryMetric> stats = metrics.getQueryMetrics();
|
||||
List<MetaQueryMetric> stats = metrics.queryMetrics();
|
||||
for (MetaQueryMetric stat : stats) {
|
||||
long meanMicros = stat.getMean();
|
||||
long meanMicros = stat.mean();
|
||||
assertThat(meanMicros).isLessThan(900_000);
|
||||
assertThat(stat.getLocation()).isSameAs(loc0.location());
|
||||
assertThat(stat.location()).isSameAs(loc0.location());
|
||||
}
|
||||
|
||||
assertThat(stats).hasSize(1);
|
||||
assertThat(stats.get(0).getCount()).isEqualTo(4);
|
||||
assertThat(stats.get(0).count()).isEqualTo(4);
|
||||
}
|
||||
|
||||
@ForPlatform(Platform.H2)
|
||||
|
||||
@@ -42,14 +42,14 @@ public class DtoQueryTest extends BaseTestCase {
|
||||
|
||||
ServerMetrics metrics = collectMetrics();
|
||||
|
||||
List<MetaQueryMetric> stats = metrics.getQueryMetrics();
|
||||
List<MetaQueryMetric> stats = metrics.queryMetrics();
|
||||
for (MetaQueryMetric stat : stats) {
|
||||
long meanMicros = stat.getMean();
|
||||
long meanMicros = stat.mean();
|
||||
assertThat(meanMicros).isLessThan(900_000);
|
||||
}
|
||||
|
||||
assertThat(stats).hasSize(1);
|
||||
assertThat(stats.get(0).getCount()).isEqualTo(1);
|
||||
assertThat(stats.get(0).count()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -283,13 +283,13 @@ public class DtoQueryTest extends BaseTestCase {
|
||||
BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true);
|
||||
server().getMetaInfoManager().visitMetrics(basic);
|
||||
|
||||
List<MetaQueryMetric> stats = basic.getQueryMetrics();
|
||||
List<MetaQueryMetric> stats = basic.queryMetrics();
|
||||
assertThat(stats).hasSize(1);
|
||||
|
||||
MetaQueryMetric queryMetric = stats.get(0);
|
||||
assertThat(queryMetric.getLabel()).isEqualTo("basic");
|
||||
assertThat(queryMetric.getCount()).isEqualTo(3);
|
||||
assertThat(queryMetric.getName()).isEqualTo("dto.DCust_basic");
|
||||
assertThat(queryMetric.label()).isEqualTo("basic");
|
||||
assertThat(queryMetric.count()).isEqualTo(3);
|
||||
assertThat(queryMetric.name()).isEqualTo("dto.DCust_basic");
|
||||
|
||||
|
||||
server().findDto(DCust.class, "select c4.id, c4.name from o_customer c4 where lower(c4.name) = :name")
|
||||
@@ -299,7 +299,7 @@ public class DtoQueryTest extends BaseTestCase {
|
||||
|
||||
ServerMetrics metric2 = server().getMetaInfoManager().collectMetrics();
|
||||
|
||||
stats = metric2.getQueryMetrics();
|
||||
stats = metric2.queryMetrics();
|
||||
assertThat(stats).hasSize(2);
|
||||
|
||||
log.info("stats " + stats);
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class EbeanServer_refresh {
|
||||
|
||||
@@ -39,8 +39,11 @@ public class EbeanServer_refresh {
|
||||
|
||||
assertEquals(rows, 1);
|
||||
|
||||
basic.setName("modify");
|
||||
assertTrue(DB.getBeanState(basic).isDirty());
|
||||
server.refresh(basic);
|
||||
assertEquals(basic.getStatus(), EBasic.Status.ACTIVE);
|
||||
assertFalse(DB.getBeanState(basic).isDirty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -39,10 +39,10 @@ public class UpdateQueryTest extends BaseTestCase {
|
||||
assertSql(query).contains("update o_customer set status=?, updtime=? where status = ? and id > ?");
|
||||
|
||||
ServerMetrics metrics = collectMetrics();
|
||||
List<MetaQueryMetric> ormQueryMetrics = metrics.getQueryMetrics();
|
||||
List<MetaQueryMetric> ormQueryMetrics = metrics.queryMetrics();
|
||||
assertThat(ormQueryMetrics).hasSize(1);
|
||||
assertThat(ormQueryMetrics.get(0).getType()).isEqualTo(Customer.class);
|
||||
assertThat(ormQueryMetrics.get(0).getLabel()).isEqualTo("updateActive");
|
||||
assertThat(ormQueryMetrics.get(0).type()).isEqualTo(Customer.class);
|
||||
assertThat(ormQueryMetrics.get(0).label()).isEqualTo("updateActive");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -69,10 +69,10 @@ public class UpdateQueryTest extends BaseTestCase {
|
||||
assertSql(sql.get(0)).contains("update o_customer set status = status");
|
||||
|
||||
ServerMetrics metrics = collectMetrics();
|
||||
List<MetaQueryMetric> ormQueryMetrics = metrics.getQueryMetrics();
|
||||
List<MetaQueryMetric> ormQueryMetrics = metrics.queryMetrics();
|
||||
assertThat(ormQueryMetrics).hasSize(1);
|
||||
assertThat(ormQueryMetrics.get(0).getType()).isEqualTo(Customer.class);
|
||||
assertThat(ormQueryMetrics.get(0).getLabel()).isEqualTo("updateAll");
|
||||
assertThat(ormQueryMetrics.get(0).type()).isEqualTo(Customer.class);
|
||||
assertThat(ormQueryMetrics.get(0).label()).isEqualTo("updateAll");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class DatabaseConfigTest {
|
||||
|
||||
@Test
|
||||
public void testLoadFromEbeanProperties() {
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.loadFromProperties();
|
||||
|
||||
assertEquals(PersistBatch.NONE, config.getPersistBatch());
|
||||
assertNotNull(config.getProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evalPropertiesInput() {
|
||||
|
||||
String home = System.getenv("HOME");
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("ddl.initSql", "${HOME}/initSql");
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.loadFromProperties(props);
|
||||
|
||||
String ddlInitSql = config.getDdlInitSql();
|
||||
assertThat(ddlInitSql).isEqualTo(home+"/initSql");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadWithProperties() {
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.setPersistBatch(PersistBatch.NONE);
|
||||
config.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
config.setAutoReadOnlyDataSource(false);
|
||||
config.setReadOnlyDataSource(null);
|
||||
config.setReadOnlyDataSourceConfig(new DataSourceConfig());
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("persistBatch", "ALL");
|
||||
props.setProperty("persistBatchOnCascade", "ALL");
|
||||
props.setProperty("dbuuid", "binary");
|
||||
props.setProperty("jdbcFetchSizeFindEach", "42");
|
||||
props.setProperty("jdbcFetchSizeFindList", "43");
|
||||
props.setProperty("backgroundExecutorShutdownSecs", "98");
|
||||
props.setProperty("backgroundExecutorSchedulePoolSize", "4");
|
||||
props.setProperty("dbOffline", "true");
|
||||
props.setProperty("jsonDateTime", "MILLIS");
|
||||
props.setProperty("jsonDate", "MILLIS");
|
||||
props.setProperty("jsonMutationDetection", "NONE");
|
||||
props.setProperty("autoReadOnlyDataSource", "true");
|
||||
props.setProperty("disableL2Cache", "true");
|
||||
props.setProperty("notifyL2CacheInForeground", "true");
|
||||
props.setProperty("idType", "SEQUENCE");
|
||||
props.setProperty("mappingLocations", "classpath:/foo;bar");
|
||||
props.setProperty("namingConvention", "io.ebean.config.MatchingNamingConvention");
|
||||
props.setProperty("idGeneratorAutomatic", "true");
|
||||
props.setProperty("enabledL2Regions", "r0,users,orgs");
|
||||
props.setProperty("caseSensitiveCollation", "false");
|
||||
props.setProperty("loadModuleInfo", "true");
|
||||
props.setProperty("forUpdateNoKey", "true");
|
||||
props.setProperty("defaultServer", "false");
|
||||
props.setProperty("skipDataSourceCheck", "true");
|
||||
|
||||
props.setProperty("queryPlan.enable", "true");
|
||||
props.setProperty("queryPlan.thresholdMicros", "10000");
|
||||
props.setProperty("queryPlan.capture", "true");
|
||||
props.setProperty("queryPlan.capturePeriodSecs", "42");
|
||||
props.setProperty("queryPlan.captureMaxTimeMillis", "560");
|
||||
props.setProperty("queryPlan.captureMaxCount", "7");
|
||||
|
||||
config.loadFromProperties(props);
|
||||
|
||||
assertFalse(config.isDefaultServer());
|
||||
assertTrue(config.isDisableL2Cache());
|
||||
assertTrue(config.isNotifyL2CacheInForeground());
|
||||
assertTrue(config.isDbOffline());
|
||||
assertTrue(config.isAutoReadOnlyDataSource());
|
||||
assertTrue(config.isAutoLoadModuleInfo());
|
||||
assertTrue(config.skipDataSourceCheck());
|
||||
|
||||
assertTrue(config.isIdGeneratorAutomatic());
|
||||
assertFalse(config.getPlatformConfig().isCaseSensitiveCollation());
|
||||
assertTrue(config.getPlatformConfig().isForUpdateNoKey());
|
||||
|
||||
assertThat(config.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class);
|
||||
|
||||
assertEquals(MutationDetection.NONE, config.getJsonMutationDetection());
|
||||
config.setJsonMutationDetection(MutationDetection.SOURCE);
|
||||
assertEquals(MutationDetection.SOURCE, config.getJsonMutationDetection());
|
||||
assertEquals(IdType.SEQUENCE, config.getIdType());
|
||||
assertEquals(PersistBatch.ALL, config.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade());
|
||||
assertEquals(PlatformConfig.DbUuid.BINARY, config.getPlatformConfig().getDbUuid());
|
||||
assertEquals(JsonConfig.DateTime.MILLIS, config.getJsonDateTime());
|
||||
assertEquals(JsonConfig.Date.MILLIS, config.getJsonDate());
|
||||
|
||||
assertEquals("r0,users,orgs", config.getEnabledL2Regions());
|
||||
|
||||
assertEquals(42, config.getJdbcFetchSizeFindEach());
|
||||
assertEquals(43, config.getJdbcFetchSizeFindList());
|
||||
assertEquals(4, config.getBackgroundExecutorSchedulePoolSize());
|
||||
assertEquals(98, config.getBackgroundExecutorShutdownSecs());
|
||||
|
||||
assertTrue(config.isQueryPlanEnable());
|
||||
assertEquals(10000, config.getQueryPlanThresholdMicros());
|
||||
assertTrue(config.isQueryPlanCapture());
|
||||
assertEquals(42, config.getQueryPlanCapturePeriodSecs());
|
||||
assertEquals(560, config.getQueryPlanCaptureMaxTimeMillis());
|
||||
assertEquals(7, config.getQueryPlanCaptureMaxCount());
|
||||
|
||||
assertThat(config.getMappingLocations()).containsExactly("classpath:/foo","bar");
|
||||
|
||||
config.setPersistBatch(PersistBatch.NONE);
|
||||
config.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
|
||||
Properties props1 = new Properties();
|
||||
props1.setProperty("ebean.persistBatch", "ALL");
|
||||
props1.setProperty("ebean.persistBatchOnCascade", "ALL");
|
||||
|
||||
config.setNotifyL2CacheInForeground(true);
|
||||
config.setDisableL2Cache(true);
|
||||
props1.setProperty("ebean.disableL2Cache", "false");
|
||||
props1.setProperty("ebean.notifyL2CacheInForeground", "false");
|
||||
|
||||
config.loadFromProperties(props1);
|
||||
assertFalse(config.isDisableL2Cache());
|
||||
assertFalse(config.isNotifyL2CacheInForeground());
|
||||
|
||||
assertEquals(PersistBatch.ALL, config.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade());
|
||||
|
||||
config.setEnabledL2Regions("r0,orgs");
|
||||
assertEquals("r0,orgs", config.getEnabledL2Regions());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_defaults() {
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
assertTrue(config.isIdGeneratorAutomatic());
|
||||
assertTrue(config.isDefaultServer());
|
||||
assertFalse(config.isAutoPersistUpdates());
|
||||
assertFalse(config.skipDataSourceCheck());
|
||||
|
||||
config.setIdGeneratorAutomatic(false);
|
||||
assertFalse(config.isIdGeneratorAutomatic());
|
||||
assertEquals(JsonConfig.DateTime.ISO8601, config.getJsonDateTime());
|
||||
assertEquals(JsonConfig.Date.ISO8601, config.getJsonDate());
|
||||
assertEquals(MutationDetection.HASH, config.getJsonMutationDetection());
|
||||
assertTrue(config.getPlatformConfig().isCaseSensitiveCollation());
|
||||
assertTrue(config.isAutoLoadModuleInfo());
|
||||
|
||||
assertFalse(config.isQueryPlanEnable());
|
||||
assertEquals(Long.MAX_VALUE, config.getQueryPlanThresholdMicros());
|
||||
assertFalse(config.isQueryPlanCapture());
|
||||
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
|
||||
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
|
||||
assertEquals(10, config.getQueryPlanCaptureMaxCount());
|
||||
|
||||
config.setLoadModuleInfo(false);
|
||||
assertFalse(config.isAutoLoadModuleInfo());
|
||||
config.setAutoPersistUpdates(true);
|
||||
assertTrue(config.isAutoPersistUpdates());
|
||||
config.setSkipDataSourceCheck(true);
|
||||
assertTrue(config.skipDataSourceCheck());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_putServiceObject() {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.putServiceObject(objectMapper);
|
||||
|
||||
ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class);
|
||||
ObjectMapper mapper1 = (ObjectMapper)config.getServiceObject("objectMapper");
|
||||
|
||||
assertThat(objectMapper).isSameAs(mapper0);
|
||||
assertThat(objectMapper).isSameAs(mapper1);
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ServerConfigTest {
|
||||
|
||||
@Test
|
||||
public void testLoadFromEbeanProperties() {
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties();
|
||||
|
||||
assertEquals(PersistBatch.NONE, serverConfig.getPersistBatch());
|
||||
assertNotNull(serverConfig.getProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evalPropertiesInput() {
|
||||
|
||||
String home = System.getenv("HOME");
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("ddl.initSql", "${HOME}/initSql");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties(props);
|
||||
|
||||
String ddlInitSql = serverConfig.getDdlInitSql();
|
||||
assertThat(ddlInitSql).isEqualTo(home+"/initSql");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadWithProperties() {
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.setPersistBatch(PersistBatch.NONE);
|
||||
serverConfig.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
serverConfig.setAutoReadOnlyDataSource(false);
|
||||
serverConfig.setReadOnlyDataSource(null);
|
||||
serverConfig.setReadOnlyDataSourceConfig(new DataSourceConfig());
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("persistBatch", "ALL");
|
||||
props.setProperty("persistBatchOnCascade", "ALL");
|
||||
props.setProperty("dbuuid", "binary");
|
||||
props.setProperty("jdbcFetchSizeFindEach", "42");
|
||||
props.setProperty("jdbcFetchSizeFindList", "43");
|
||||
props.setProperty("backgroundExecutorShutdownSecs", "98");
|
||||
props.setProperty("backgroundExecutorSchedulePoolSize", "4");
|
||||
props.setProperty("dbOffline", "true");
|
||||
props.setProperty("jsonDateTime", "MILLIS");
|
||||
props.setProperty("jsonDate", "MILLIS");
|
||||
props.setProperty("jsonDirtyByDefault", "false");
|
||||
props.setProperty("autoReadOnlyDataSource", "true");
|
||||
props.setProperty("disableL2Cache", "true");
|
||||
props.setProperty("notifyL2CacheInForeground", "true");
|
||||
props.setProperty("idType", "SEQUENCE");
|
||||
props.setProperty("mappingLocations", "classpath:/foo;bar");
|
||||
props.setProperty("namingConvention", "io.ebean.config.MatchingNamingConvention");
|
||||
props.setProperty("idGeneratorAutomatic", "true");
|
||||
props.setProperty("enabledL2Regions", "r0,users,orgs");
|
||||
props.setProperty("caseSensitiveCollation", "false");
|
||||
props.setProperty("loadModuleInfo", "true");
|
||||
props.setProperty("forUpdateNoKey", "true");
|
||||
props.setProperty("defaultServer", "false");
|
||||
|
||||
props.setProperty("queryPlan.enable", "true");
|
||||
props.setProperty("queryPlan.thresholdMicros", "10000");
|
||||
props.setProperty("queryPlan.capture", "true");
|
||||
props.setProperty("queryPlan.capturePeriodSecs", "42");
|
||||
props.setProperty("queryPlan.captureMaxTimeMillis", "560");
|
||||
props.setProperty("queryPlan.captureMaxCount", "7");
|
||||
|
||||
serverConfig.loadFromProperties(props);
|
||||
|
||||
assertFalse(serverConfig.isDefaultServer());
|
||||
assertTrue(serverConfig.isDisableL2Cache());
|
||||
assertTrue(serverConfig.isNotifyL2CacheInForeground());
|
||||
assertTrue(serverConfig.isDbOffline());
|
||||
assertTrue(serverConfig.isAutoReadOnlyDataSource());
|
||||
assertTrue(serverConfig.isAutoLoadModuleInfo());
|
||||
|
||||
assertTrue(serverConfig.isIdGeneratorAutomatic());
|
||||
assertFalse(serverConfig.getPlatformConfig().isCaseSensitiveCollation());
|
||||
assertTrue(serverConfig.getPlatformConfig().isForUpdateNoKey());
|
||||
|
||||
assertThat(serverConfig.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class);
|
||||
|
||||
assertEquals(IdType.SEQUENCE, serverConfig.getIdType());
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade());
|
||||
assertEquals(PlatformConfig.DbUuid.BINARY, serverConfig.getPlatformConfig().getDbUuid());
|
||||
assertEquals(JsonConfig.DateTime.MILLIS, serverConfig.getJsonDateTime());
|
||||
assertEquals(JsonConfig.Date.MILLIS, serverConfig.getJsonDate());
|
||||
assertFalse(serverConfig.isJsonDirtyByDefault());
|
||||
serverConfig.setJsonDirtyByDefault(true);
|
||||
assertTrue(serverConfig.isJsonDirtyByDefault());
|
||||
|
||||
assertEquals("r0,users,orgs", serverConfig.getEnabledL2Regions());
|
||||
|
||||
assertEquals(42, serverConfig.getJdbcFetchSizeFindEach());
|
||||
assertEquals(43, serverConfig.getJdbcFetchSizeFindList());
|
||||
assertEquals(4, serverConfig.getBackgroundExecutorSchedulePoolSize());
|
||||
assertEquals(98, serverConfig.getBackgroundExecutorShutdownSecs());
|
||||
|
||||
assertTrue(serverConfig.isQueryPlanEnable());
|
||||
assertEquals(10000, serverConfig.getQueryPlanThresholdMicros());
|
||||
assertTrue(serverConfig.isQueryPlanCapture());
|
||||
assertEquals(42, serverConfig.getQueryPlanCapturePeriodSecs());
|
||||
assertEquals(560, serverConfig.getQueryPlanCaptureMaxTimeMillis());
|
||||
assertEquals(7, serverConfig.getQueryPlanCaptureMaxCount());
|
||||
|
||||
assertThat(serverConfig.getMappingLocations()).containsExactly("classpath:/foo","bar");
|
||||
|
||||
serverConfig.setPersistBatch(PersistBatch.NONE);
|
||||
serverConfig.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
|
||||
Properties props1 = new Properties();
|
||||
props1.setProperty("ebean.persistBatch", "ALL");
|
||||
props1.setProperty("ebean.persistBatchOnCascade", "ALL");
|
||||
|
||||
serverConfig.setNotifyL2CacheInForeground(true);
|
||||
serverConfig.setDisableL2Cache(true);
|
||||
props1.setProperty("ebean.disableL2Cache", "false");
|
||||
props1.setProperty("ebean.notifyL2CacheInForeground", "false");
|
||||
|
||||
serverConfig.loadFromProperties(props1);
|
||||
assertFalse(serverConfig.isDisableL2Cache());
|
||||
assertFalse(serverConfig.isNotifyL2CacheInForeground());
|
||||
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade());
|
||||
|
||||
serverConfig.setEnabledL2Regions("r0,orgs");
|
||||
assertEquals("r0,orgs", serverConfig.getEnabledL2Regions());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_defaults() {
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
assertTrue(serverConfig.isIdGeneratorAutomatic());
|
||||
assertTrue(serverConfig.isDefaultServer());
|
||||
assertFalse(serverConfig.isAutoPersistUpdates());
|
||||
|
||||
serverConfig.setIdGeneratorAutomatic(false);
|
||||
assertFalse(serverConfig.isIdGeneratorAutomatic());
|
||||
assertEquals(JsonConfig.DateTime.ISO8601, serverConfig.getJsonDateTime());
|
||||
assertEquals(JsonConfig.Date.ISO8601, serverConfig.getJsonDate());
|
||||
assertTrue(serverConfig.isJsonDirtyByDefault());
|
||||
assertTrue(serverConfig.getPlatformConfig().isCaseSensitiveCollation());
|
||||
assertTrue(serverConfig.isAutoLoadModuleInfo());
|
||||
|
||||
assertFalse(serverConfig.isQueryPlanEnable());
|
||||
assertEquals(Long.MAX_VALUE, serverConfig.getQueryPlanThresholdMicros());
|
||||
assertFalse(serverConfig.isQueryPlanCapture());
|
||||
assertEquals(600, serverConfig.getQueryPlanCapturePeriodSecs());
|
||||
assertEquals(10000L, serverConfig.getQueryPlanCaptureMaxTimeMillis());
|
||||
assertEquals(10, serverConfig.getQueryPlanCaptureMaxCount());
|
||||
|
||||
serverConfig.setLoadModuleInfo(false);
|
||||
assertFalse(serverConfig.isAutoLoadModuleInfo());
|
||||
serverConfig.setAutoPersistUpdates(true);
|
||||
assertTrue(serverConfig.isAutoPersistUpdates());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_putServiceObject() {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
ServerConfig config = new ServerConfig();
|
||||
config.putServiceObject(objectMapper);
|
||||
|
||||
ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class);
|
||||
ObjectMapper mapper1 = (ObjectMapper)config.getServiceObject("objectMapper");
|
||||
|
||||
assertThat(objectMapper).isSameAs(mapper0);
|
||||
assertThat(objectMapper).isSameAs(mapper1);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.server.core.SpiResultSet;
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -54,7 +55,6 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Clock;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -256,7 +256,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t) {
|
||||
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedType(Type genericType) {
|
||||
public boolean isSupportedType(java.lang.reflect.Type genericType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -20,8 +20,7 @@ public class ChangeJsonBuilderTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testToJson() throws Exception {
|
||||
|
||||
JsonContext jsonContext = Ebean.getDefaultServer().json();
|
||||
ChangeJsonBuilder builder = new ChangeJsonBuilder(jsonContext);
|
||||
ChangeJsonBuilder builder = new ChangeJsonBuilder();
|
||||
|
||||
ChangeSet changeSet = helper.createChangeSet("ABCD", 10);
|
||||
changeSet.getUserContext().put("altUser", "role user");
|
||||
|
||||
@@ -29,7 +29,7 @@ public class BindPaddingTest {
|
||||
|
||||
@Test
|
||||
public void padding() {
|
||||
|
||||
assertEquals(0, BindPadding.padding(0));
|
||||
assertEquals(0, BindPadding.padding(1));
|
||||
assertEquals(3, BindPadding.padding(2));
|
||||
assertEquals(2, BindPadding.padding(3));
|
||||
|
||||
@@ -23,11 +23,11 @@ public class BeanIudMetricsTest {
|
||||
BasicMetricVisitor basic = new BasicMetricVisitor();
|
||||
iudMetrics.visit(basic);
|
||||
|
||||
List<MetaTimedMetric> timed = basic.getTimedMetrics();
|
||||
List<MetaTimedMetric> timed = basic.timedMetrics();
|
||||
assertThat(timed).hasSize(1);
|
||||
|
||||
assertThat(timed.get(0).getCount()).isEqualTo(4);
|
||||
assertThat(timed.get(0).getName()).isEqualTo("iud.one.insertBatch");
|
||||
assertThat(timed.get(0).count()).isEqualTo(4);
|
||||
assertThat(timed.get(0).name()).isEqualTo("iud.one.insertBatch");
|
||||
|
||||
iudMetrics.addBatch(PersistRequest.Type.UPDATE, startNanos, 1);
|
||||
iudMetrics.addBatch(PersistRequest.Type.DELETE_SOFT, startNanos, 2);
|
||||
@@ -37,15 +37,15 @@ public class BeanIudMetricsTest {
|
||||
|
||||
basic = new BasicMetricVisitor();
|
||||
iudMetrics.visit(basic);
|
||||
timed = basic.getTimedMetrics();
|
||||
timed = basic.timedMetrics();
|
||||
assertThat(timed).hasSize(3);
|
||||
|
||||
assertThat(timed.get(0).getCount()).isEqualTo(16);
|
||||
assertThat(timed.get(0).getName()).isEqualTo("iud.one.insertBatch");
|
||||
assertThat(timed.get(1).getCount()).isEqualTo(3);
|
||||
assertThat(timed.get(1).getName()).isEqualTo("iud.one.updateBatch");
|
||||
assertThat(timed.get(2).getCount()).isEqualTo(12);
|
||||
assertThat(timed.get(2).getName()).isEqualTo("iud.one.deleteBatch");
|
||||
assertThat(timed.get(0).count()).isEqualTo(16);
|
||||
assertThat(timed.get(0).name()).isEqualTo("iud.one.insertBatch");
|
||||
assertThat(timed.get(1).count()).isEqualTo(3);
|
||||
assertThat(timed.get(1).name()).isEqualTo("iud.one.updateBatch");
|
||||
assertThat(timed.get(2).count()).isEqualTo(12);
|
||||
assertThat(timed.get(2).name()).isEqualTo("iud.one.deleteBatch");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -63,15 +63,15 @@ public class BeanIudMetricsTest {
|
||||
BasicMetricVisitor basic = new BasicMetricVisitor();
|
||||
iudMetrics.visit(basic);
|
||||
|
||||
List<MetaTimedMetric> timed = basic.getTimedMetrics();
|
||||
List<MetaTimedMetric> timed = basic.timedMetrics();
|
||||
assertThat(timed).hasSize(3);
|
||||
|
||||
assertThat(timed.get(0).getCount()).isEqualTo(1);
|
||||
assertThat(timed.get(0).getName()).isEqualTo("iud.one.insert");
|
||||
assertThat(timed.get(1).getCount()).isEqualTo(2);
|
||||
assertThat(timed.get(1).getName()).isEqualTo("iud.one.update");
|
||||
assertThat(timed.get(2).getCount()).isEqualTo(2);
|
||||
assertThat(timed.get(2).getName()).isEqualTo("iud.one.delete");
|
||||
assertThat(timed.get(0).count()).isEqualTo(1);
|
||||
assertThat(timed.get(0).name()).isEqualTo("iud.one.insert");
|
||||
assertThat(timed.get(1).count()).isEqualTo(2);
|
||||
assertThat(timed.get(1).name()).isEqualTo("iud.one.update");
|
||||
assertThat(timed.get(2).count()).isEqualTo(2);
|
||||
assertThat(timed.get(2).name()).isEqualTo("iud.one.delete");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-3
@@ -1,12 +1,16 @@
|
||||
package io.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
|
||||
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@@ -46,9 +50,8 @@ public class AnnotationClassTest {
|
||||
|
||||
DeployUtil deployUtil = new DeployUtil(new DefaultTypeManager(config, new BootupClasses()), config);
|
||||
|
||||
DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, mock(DeployBeanDescriptor.class));
|
||||
ReadAnnotationConfig readAnnotationConfig = mock(ReadAnnotationConfig.class);
|
||||
|
||||
DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, new DeployBeanDescriptor<>(null, null, null));
|
||||
ReadAnnotationConfig readAnnotationConfig = new ReadAnnotationConfig(new GeneratedPropertyFactory(true, new DatabaseConfig(), Collections.emptyList()), "","", new DatabaseConfig());
|
||||
return new AnnotationClass(deployBeanInfo, readAnnotationConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.expression;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import io.ebeaninternal.api.BindValuesKey;
|
||||
|
||||
public class RawExpressionTest extends BaseExpressionTest {
|
||||
|
||||
@@ -61,11 +62,16 @@ public class RawExpressionTest extends BaseExpressionTest {
|
||||
}
|
||||
|
||||
public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) {
|
||||
assertThat(exp0.queryBindHash()).isNotEqualTo(exp1.queryBindHash());
|
||||
assertThat(bindKey(exp0)).isNotEqualTo(bindKey(exp1));
|
||||
}
|
||||
|
||||
public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) {
|
||||
assertThat(exp0.queryBindHash()).isEqualTo(exp1.queryBindHash());
|
||||
assertThat(bindKey(exp0)).isEqualTo(bindKey(exp1));
|
||||
}
|
||||
|
||||
private BindValuesKey bindKey(RawExpression query) {
|
||||
BindValuesKey bindValuesKey = new BindValuesKey();
|
||||
query.queryBindKey(bindValuesKey);
|
||||
return bindValuesKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,39 +2,32 @@
|
||||
* Licensed Materials - Property of FOCONIS AG
|
||||
* (C) Copyright FOCONIS AG.
|
||||
*/
|
||||
|
||||
package io.ebeaninternal.server.idgen;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Run some simple tests for the UUID generator.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
public class TestUuidGenerator {
|
||||
|
||||
|
||||
/**
|
||||
* Worker to generate UUIDs
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Worker to generate UUIDs
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public static class IdTest implements Runnable {
|
||||
private final Map<UUID, UUID> map;
|
||||
private final Map<UUID, UUID> map;
|
||||
private final PlatformIdGenerator idGen;
|
||||
private final int ids;
|
||||
private final AtomicBoolean failFlag;
|
||||
@@ -46,12 +39,6 @@ public class TestUuidGenerator {
|
||||
this.failFlag = failFlag;
|
||||
}
|
||||
|
||||
public IdTest(PlatformIdGenerator idGen, int ids) {
|
||||
this.idGen = idGen;
|
||||
this.ids = ids;
|
||||
this.map = null;
|
||||
this.failFlag = null;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
//System.out.println("Start " + Thread.currentThread());
|
||||
@@ -70,7 +57,7 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidV1SingleThread() throws Exception {
|
||||
testGenerator(1, 1_000_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state"));
|
||||
testGenerator(1, 500_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +65,7 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidV1MultiThread() throws Exception {
|
||||
testGenerator(10, 100_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state"));
|
||||
testGenerator(10, 50_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +73,7 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidV1RndMultiThread() throws Exception {
|
||||
testGenerator(10, 100_000, UuidV1RndIdGenerator.INSTANCE);
|
||||
testGenerator(10, 50_000, UuidV1RndIdGenerator.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +81,7 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidType1RndSingleThread() throws Exception {
|
||||
testGenerator(1, 1_000_000, UuidV1RndIdGenerator.INSTANCE);
|
||||
testGenerator(1, 500_000, UuidV1RndIdGenerator.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +89,7 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidType4MultiThread() throws Exception {
|
||||
testGenerator(10, 100_000, UuidV4IdGenerator.INSTANCE);
|
||||
testGenerator(10, 50_000, UuidV4IdGenerator.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,12 +97,9 @@ public class TestUuidGenerator {
|
||||
*/
|
||||
@Test
|
||||
public void testUuidType4SingleThread() throws Exception {
|
||||
testGenerator(1, 1_000_000, UuidV4IdGenerator.INSTANCE);
|
||||
testGenerator(1, 500_000, UuidV4IdGenerator.INSTANCE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void testGenerator(int threadCount, int count, PlatformIdGenerator generator) throws Exception {
|
||||
System.out.println("Printing 5 consecutive IDs of " + generator);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
@@ -136,6 +120,5 @@ public class TestUuidGenerator {
|
||||
}
|
||||
assertThat(failFlag.get()).isFalse();
|
||||
assertThat(map.size()).isEqualTo(threadCount * count);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,60 @@ package io.ebeaninternal.server.lib;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.DatabaseFactory;
|
||||
import io.ebean.event.ShutdownManager;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ShutdownManagerTest extends BaseTestCase {
|
||||
|
||||
/**
|
||||
* Run this test manually. Most typical when we want the application code to control shutdown.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void test_disableShutdownHook_shutdownManually() {
|
||||
// disable hook to make sure app code controls when shutdown is executed
|
||||
ShutdownManager.deregisterShutdownHook();
|
||||
DB.getDefault();
|
||||
|
||||
System.out.println("shutdown manually ... ");
|
||||
// application code explicitly calls shutdown()
|
||||
ShutdownManager.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this test manually.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void test_shutdownHook() {
|
||||
DB.getDefault(); // shutdown fired via shutdown hook, default behaviour
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this test manually.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void test_disableShutdownHook() {
|
||||
DB.getDefault();
|
||||
ShutdownManager.deregisterShutdownHook(); // no shutdown is run here (not great, don't do this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this test manually.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void test_shutdownManually() {
|
||||
DB.getDefault();
|
||||
System.out.println("shutdown manually ... ");
|
||||
// note this removes the shutdown hook, only "useful" if it runs BEFORE a JVM shutdown is invoked (hook invoked)
|
||||
DatabaseFactory.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this test manually.
|
||||
*/
|
||||
|
||||
+7
-3
@@ -14,7 +14,11 @@ public class BasicProfileLocationTest {
|
||||
|
||||
assertThat(loc.obtain()).isTrue();
|
||||
assertThat(loc.fullLocation()).endsWith(":12)");
|
||||
assertThat(loc.location()).isEqualTo("NativeMethodAccessorImpl.invoke0(Native Method:12)");
|
||||
if (System.getProperty("java.version").startsWith("1.8")) {
|
||||
assertThat(loc.location()).isEqualTo("sun.reflect.NativeMethodAccessorImpl.invoke0");
|
||||
} else {
|
||||
assertThat(loc.location()).isEqualTo("java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0");
|
||||
}
|
||||
assertThat(loc.label()).isEqualTo("NativeMethodAccessorImpl.invoke0");
|
||||
}
|
||||
|
||||
@@ -24,7 +28,7 @@ public class BasicProfileLocationTest {
|
||||
BasicProfileLocation loc = new BasicProfileLocation("com.foo.Bar.all");
|
||||
assertThat(loc.obtain()).isFalse();
|
||||
assertThat(loc.fullLocation()).isEqualTo("com.foo.Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("com.foo.Bar.all");
|
||||
assertThat(loc.label()).isEqualTo("Bar.all");
|
||||
}
|
||||
|
||||
@@ -34,7 +38,7 @@ public class BasicProfileLocationTest {
|
||||
BasicProfileLocation loc = new BasicProfileLocation("foo.Bar.all");
|
||||
assertThat(loc.obtain()).isFalse();
|
||||
assertThat(loc.fullLocation()).isEqualTo("foo.Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("Bar.all");
|
||||
assertThat(loc.location()).isEqualTo("foo.Bar.all");
|
||||
assertThat(loc.label()).isEqualTo("Bar.all");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,17 @@ public class DTimedMetricMapTest {
|
||||
BasicMetricVisitor visitor = new BasicMetricVisitor();
|
||||
metricMap.visit(visitor);
|
||||
|
||||
MetaTimedMetric timedMetric = visitor.getTimedMetrics().get(0);
|
||||
assertThat(timedMetric.getCount()).isEqualTo(1);
|
||||
assertThat(timedMetric.getTotal()).isGreaterThan(10);
|
||||
MetaTimedMetric timedMetric = visitor.timedMetrics().get(0);
|
||||
assertThat(timedMetric.count()).isEqualTo(1);
|
||||
assertThat(timedMetric.total()).isGreaterThan(10);
|
||||
|
||||
metricMap.addSinceNanos("some", nanos);
|
||||
|
||||
visitor = new BasicMetricVisitor();
|
||||
metricMap.visit(visitor);
|
||||
|
||||
timedMetric = visitor.getTimedMetrics().get(0);
|
||||
assertThat(timedMetric.getCount()).isEqualTo(1);
|
||||
assertThat(timedMetric.getTotal()).isGreaterThan(10);
|
||||
timedMetric = visitor.timedMetrics().get(0);
|
||||
assertThat(timedMetric.count()).isEqualTo(1);
|
||||
assertThat(timedMetric.total()).isGreaterThan(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,16 +17,16 @@ public class DTimedMetricTest {
|
||||
metric.addSinceNanos(start);
|
||||
|
||||
DTimeMetricStats stats = metric.collect(true);
|
||||
assertThat(stats.getCount()).isEqualTo(1);
|
||||
assertThat(stats.getTotal()).isGreaterThan(10);
|
||||
assertThat(stats.getMax()).isEqualTo(stats.getTotal());
|
||||
assertThat(stats.count()).isEqualTo(1);
|
||||
assertThat(stats.total()).isGreaterThan(10);
|
||||
assertThat(stats.max()).isEqualTo(stats.total());
|
||||
|
||||
metric.addSinceNanos(start);
|
||||
|
||||
stats = metric.collect(true);
|
||||
assertThat(stats.getCount()).isEqualTo(1);
|
||||
assertThat(stats.getTotal()).isGreaterThan(10);
|
||||
assertThat(stats.getMax()).isEqualTo(stats.getTotal());
|
||||
assertThat(stats.count()).isEqualTo(1);
|
||||
assertThat(stats.total()).isGreaterThan(10);
|
||||
assertThat(stats.max()).isEqualTo(stats.total());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -40,16 +40,16 @@ public class DTimedMetricTest {
|
||||
metric.addBatchSince(start, 5);
|
||||
|
||||
DTimeMetricStats stats = metric.collect(true);
|
||||
assertThat(stats.getCount()).isEqualTo(5);
|
||||
assertThat(stats.getTotal()).isGreaterThan(10000);
|
||||
assertThat(stats.getMax()).isEqualTo(stats.getTotal() / 5);
|
||||
assertThat(stats.getMax()).isGreaterThan(10000 / 5);
|
||||
assertThat(stats.count()).isEqualTo(5);
|
||||
assertThat(stats.total()).isGreaterThan(10000);
|
||||
assertThat(stats.max()).isEqualTo(stats.total() / 5);
|
||||
assertThat(stats.max()).isGreaterThan(10000 / 5);
|
||||
|
||||
metric.addBatchSince(start, 2);
|
||||
|
||||
stats = metric.collect(true);
|
||||
assertThat(stats.getCount()).isEqualTo(2);
|
||||
assertThat(stats.getTotal()).isGreaterThan(10000);
|
||||
assertThat(stats.getMax()).isEqualTo(stats.getTotal() / 2);
|
||||
assertThat(stats.count()).isEqualTo(2);
|
||||
assertThat(stats.total()).isGreaterThan(10000);
|
||||
assertThat(stats.max()).isEqualTo(stats.total() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SortMetricTest {
|
||||
list.add(create("a"));
|
||||
list.sort(sortMetric);
|
||||
|
||||
String names = list.stream().map(DTimeMetricStats::getName).collect(Collectors.joining());
|
||||
String names = list.stream().map(DTimeMetricStats::name).collect(Collectors.joining());
|
||||
|
||||
assertEquals("nullabcd", names);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,13 @@ public class UtilLocationTest {
|
||||
|
||||
@Test
|
||||
public void label() {
|
||||
|
||||
assertThat(UtilLocation.label("foo")).isEqualTo("foo");
|
||||
assertThat(UtilLocation.label("ProfileLocationTest$Other.<init>(ProfileLocationTest.java:47)")).isEqualTo("ProfileLocationTest$Other.init");
|
||||
assertThat(UtilLocation.label("ProfileLocationTest$Other.<init>")).isEqualTo("ProfileLocationTest$Other.init");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loc() {
|
||||
assertThat(UtilLocation.loc("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo("org.foo.MyFoo.doIt");
|
||||
assertThat(UtilLocation.label("org.foo.MyFoo.doIt")).isEqualTo("MyFoo.doIt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.ebeaninternal.api.BindValuesKey;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BindValuesKeyTest {
|
||||
|
||||
@Test
|
||||
public void update_with_null() {
|
||||
|
||||
BindValuesKey hash = new BindValuesKey();
|
||||
hash.add(1).add(null).add("hello");
|
||||
|
||||
BindValuesKey hash2 = new BindValuesKey();
|
||||
hash2.add(1).add(null).add("hello");
|
||||
|
||||
assertThat(hash).isEqualTo(hash2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notEqual() {
|
||||
|
||||
BindValuesKey hash = new BindValuesKey();
|
||||
hash.add(1).add(null).add("hello");
|
||||
|
||||
BindValuesKey hash2 = new BindValuesKey();
|
||||
hash2.add(1).add("hello");
|
||||
|
||||
BindValuesKey hash3 = new BindValuesKey();
|
||||
hash2.add(1).add(null);
|
||||
|
||||
assertThat(hash).isNotEqualTo(hash2);
|
||||
assertThat(hash).isNotEqualTo(hash3);
|
||||
assertThat(hash2).isNotEqualTo(hash3);
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -4,6 +4,7 @@ package io.ebeaninternal.server.querydefn;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebeaninternal.api.BindValuesKey;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import org.junit.Test;
|
||||
@@ -62,7 +63,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
||||
|
||||
prepare(q1, q2);
|
||||
assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey());
|
||||
assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash());
|
||||
assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,7 +74,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
||||
|
||||
prepare(q1, q2);
|
||||
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
||||
assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash());
|
||||
assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,7 +85,7 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
||||
|
||||
prepare(q1, q2);
|
||||
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
|
||||
assertThat(q1.queryBindHash()).isEqualTo(q2.queryBindHash());
|
||||
assertThat(bindKey(q1)).isEqualTo(bindKey(q2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -110,4 +111,10 @@ public class DefaultOrmQueryTest extends BaseTestCase {
|
||||
OrmQueryRequest<T> r2 = createQueryRequest(SpiQuery.Type.LIST, q2, null);
|
||||
q2.prepare(r2);
|
||||
}
|
||||
|
||||
private BindValuesKey bindKey(DefaultOrmQuery<Order> query) {
|
||||
BindValuesKey key = new BindValuesKey();
|
||||
query.queryBindKey(key);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,19 +11,19 @@ public class ScalarTypeJsonListTest extends BasePlatformArrayTypeFactoryTest {
|
||||
@Test
|
||||
public void typeFor_expect_nullToEmpty_when_postgresNonNull() throws SQLException {
|
||||
|
||||
assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, false));
|
||||
assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, false));
|
||||
assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, false, false));
|
||||
assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, false, false));
|
||||
|
||||
assertBindNullTo_EmptyString(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, false));
|
||||
assertBindNullTo_EmptyString(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, false, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeFor_expect_nullToNull_when_nullable() throws SQLException {
|
||||
|
||||
assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, true));
|
||||
assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, true));
|
||||
assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, true, false));
|
||||
assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, true, false));
|
||||
|
||||
assertBindNullTo_Null(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, true));
|
||||
assertBindNullTo_Null(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, true, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.tests.unitinternal;
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebeaninternal.server.type.ScalarTypeLocale;
|
||||
import org.junit.Assert;
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
package io.ebean.server.type;
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebean.server.type.MyDayOfWeek;
|
||||
import io.ebean.server.type.MyEnum;
|
||||
import io.ebean.server.type.MySex;
|
||||
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
import io.ebeaninternal.server.type.RsetDataReader;
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.ebeaninternal.server.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ChecksumTest {
|
||||
|
||||
@Test
|
||||
public void checksum() {
|
||||
final long val = Checksum.checksum("Hello world");
|
||||
assertThat(val).isEqualTo(2346098258L);
|
||||
assertThat(Checksum.checksum("Hello world")).isEqualTo(val);
|
||||
assertThat(Checksum.checksum("hello world")).isNotEqualTo(val);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checksum_shortString() {
|
||||
final long val0 = Checksum.checksum("2012-01-11");
|
||||
final long val1 = Checksum.checksum("2012-10-02");
|
||||
assertThat(val0).isNotEqualTo(val1);
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,51 @@ package io.ebeaninternal.server.util;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class Md5Test {
|
||||
|
||||
@Test
|
||||
public void hash() throws Exception {
|
||||
|
||||
String content = "some random content we wish to hash";
|
||||
String hash1 = Md5.hash(content);
|
||||
String hash2 = Md5.hash(content);
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "62c20bf679ff56cb746452ab5c88e3ed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashDifferent() throws Exception {
|
||||
String hash1 = Md5.hash("one");
|
||||
String hash2 = Md5.hash("two");
|
||||
String hash3 = Md5.hash("onetwo");
|
||||
|
||||
assertNotEquals(hash1, hash2);
|
||||
assertNotEquals(hash2, hash3);
|
||||
assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashMulti() {
|
||||
String hash1 = Md5.hash("one", "two");
|
||||
String hash2 = Md5.hash("onetwo");
|
||||
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "5b9164ad6f496d9dee12ec7634ce253f");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashMulti_when_null() {
|
||||
String hash1 = Md5.hash("one", null);
|
||||
String hash2 = Md5.hash("one");
|
||||
|
||||
assertEquals(hash1, hash2);
|
||||
assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_null() {
|
||||
String hash1 = Md5.hash(null, null);
|
||||
assertEquals(hash1, "d41d8cd98f00b204e9800998ecf8427e");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,15 +80,15 @@ public class TestBatchInsertFlush extends BaseTestCase {
|
||||
}
|
||||
|
||||
ServerMetrics metrics = collectMetrics();
|
||||
List<MetaTimedMetric> txnStats = metrics.getTimedMetrics();
|
||||
List<MetaTimedMetric> txnStats = metrics.timedMetrics();
|
||||
for (MetaTimedMetric txnMetric : txnStats) {
|
||||
System.out.println(txnMetric);
|
||||
}
|
||||
assertThat(txnStats).hasSize(4);
|
||||
assertThat(txnStats.get(0).getName()).isEqualTo("txn.main");
|
||||
assertThat(txnStats.get(1).getName()).isEqualTo("txn.named.TestBatchInsertFlush.no_cascade");
|
||||
assertThat(txnStats.get(2).getName()).isEqualTo("iud.TSDetail.insertBatch");
|
||||
assertThat(txnStats.get(3).getName()).isEqualTo("iud.TSMaster.insertBatch");
|
||||
assertThat(txnStats.get(0).name()).isEqualTo("txn.main");
|
||||
assertThat(txnStats.get(1).name()).isEqualTo("txn.named.TestBatchInsertFlush.no_cascade");
|
||||
assertThat(txnStats.get(2).name()).isEqualTo("iud.TSDetail.insertBatch");
|
||||
assertThat(txnStats.get(3).name()).isEqualTo("iud.TSMaster.insertBatch");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+58
-28
@@ -3,7 +3,7 @@ package org.tests.cache;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
@@ -14,6 +14,7 @@ import org.tests.model.basic.ResetBasicData;
|
||||
import org.tests.model.cache.EColAB;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -26,8 +27,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
new EColAB("02", "10").save();
|
||||
|
||||
List<EColAB> list1 =
|
||||
Ebean.getServer(null)
|
||||
.find(EColAB.class)
|
||||
DB.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.where()
|
||||
.eq("columnA", "01")
|
||||
@@ -35,8 +35,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
.findList();
|
||||
|
||||
List<EColAB> list2 =
|
||||
Ebean.getServer(null)
|
||||
.find(EColAB.class)
|
||||
DB.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.where()
|
||||
.eq("columnA", "02")
|
||||
@@ -57,7 +56,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
new EColAB("03", "SingleAttribute").save();
|
||||
new EColAB("03", "SingleAttribute").save();
|
||||
|
||||
List<String> colA_first = Ebean.getServer(null)
|
||||
List<String> colA_first = DB
|
||||
.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.setDistinct(true)
|
||||
@@ -66,7 +65,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
.eq("columnB", "SingleAttribute")
|
||||
.findSingleAttributeList();
|
||||
|
||||
List<String> colA_Second = Ebean.getServer(null)
|
||||
List<String> colA_Second = DB
|
||||
.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.setDistinct(true)
|
||||
@@ -77,7 +76,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
assertThat(colA_Second).isSameAs(colA_first);
|
||||
|
||||
List<String> colA_NotDistinct = Ebean.getServer(null)
|
||||
List<String> colA_NotDistinct = DB
|
||||
.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.select("columnA")
|
||||
@@ -89,7 +88,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
// ensure that findCount & findSingleAttribute use different
|
||||
// slots in cache. If not a "Cannot cast List to int" should happen.
|
||||
int count = Ebean.getServer(null)
|
||||
int count = DB
|
||||
.find(EColAB.class)
|
||||
.setUseQueryCache(true)
|
||||
.select("columnA")
|
||||
@@ -107,13 +106,13 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
int count0 = Ebean.find(EColAB.class)
|
||||
int count0 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "count")
|
||||
.findCount();
|
||||
|
||||
int count1 = Ebean.find(EColAB.class)
|
||||
int count1 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "count")
|
||||
@@ -126,7 +125,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
// and now, ensure that we hit the database
|
||||
LoggedSqlCollector.start();
|
||||
int count2 = Ebean.find(EColAB.class)
|
||||
int count2 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.OFF)
|
||||
.where()
|
||||
.eq("columnB", "count")
|
||||
@@ -142,13 +141,13 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
int count0 = Ebean.find(EColAB.class)
|
||||
int count0 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "abc")
|
||||
.findCount();
|
||||
|
||||
int count1 = Ebean.find(EColAB.class)
|
||||
int count1 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "def")
|
||||
@@ -167,13 +166,13 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
int count0 = Ebean.find(EColAB.class)
|
||||
int count0 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "uvw")
|
||||
.findCount();
|
||||
|
||||
int count1 = Ebean.find(EColAB.class)
|
||||
int count1 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.PUT)
|
||||
.where()
|
||||
.eq("columnB", "uvw")
|
||||
@@ -193,13 +192,13 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
int count0 = Ebean.find(EColAB.class)
|
||||
int count0 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.PUT)
|
||||
.where()
|
||||
.eq("columnB", "xyz")
|
||||
.findCount();
|
||||
|
||||
int count1 = Ebean.find(EColAB.class)
|
||||
int count1 = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "xyz")
|
||||
@@ -214,26 +213,26 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void test() {
|
||||
public void testReadOnlyFind() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
ServerCache customerCache = Ebean.getServerCacheManager().getQueryCache(Customer.class);
|
||||
ServerCache customerCache = DB.getServerCacheManager().getQueryCache(Customer.class);
|
||||
customerCache.clear();
|
||||
|
||||
List<Customer> list = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||
List<Customer> list = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||
.ilike("name", "Rob").findList();
|
||||
|
||||
BeanCollection<Customer> bc = (BeanCollection<Customer>) list;
|
||||
Assert.assertTrue(bc.isReadOnly());
|
||||
Assert.assertFalse(bc.isEmpty());
|
||||
Assert.assertTrue(!list.isEmpty());
|
||||
Assert.assertTrue(Ebean.getBeanState(list.get(0)).isReadOnly());
|
||||
Assert.assertTrue(DB.getBeanState(list.get(0)).isReadOnly());
|
||||
|
||||
List<Customer> list2 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||
List<Customer> list2 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where()
|
||||
.ilike("name", "Rob").findList();
|
||||
|
||||
List<Customer> list2B = Ebean.find(Customer.class).setUseQueryCache(true)
|
||||
List<Customer> list2B = DB.find(Customer.class).setUseQueryCache(true)
|
||||
// .setReadOnly(true)
|
||||
.where().ilike("name", "Rob").findList();
|
||||
|
||||
@@ -245,7 +244,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
|
||||
|
||||
List<Customer> list3 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where()
|
||||
List<Customer> list3 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where()
|
||||
.ilike("name", "Rob").findList();
|
||||
|
||||
Assert.assertNotSame(list, list3);
|
||||
@@ -269,13 +268,13 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<Integer> colA_first = Ebean.find(EColAB.class)
|
||||
List<Integer> colA_first = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "someId")
|
||||
.findIds();
|
||||
|
||||
List<Integer> colA_second = Ebean.find(EColAB.class)
|
||||
List<Integer> colA_second = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.ON)
|
||||
.where()
|
||||
.eq("columnB", "someId")
|
||||
@@ -289,7 +288,7 @@ public class TestQueryCache extends BaseTestCase {
|
||||
|
||||
// and now, ensure that we hit the database
|
||||
LoggedSqlCollector.start();
|
||||
colA_second = Ebean.find(EColAB.class)
|
||||
colA_second = DB.find(EColAB.class)
|
||||
.setUseQueryCache(CacheMode.PUT)
|
||||
.where()
|
||||
.eq("columnB", "someId")
|
||||
@@ -299,4 +298,35 @@ public class TestQueryCache extends BaseTestCase {
|
||||
assertThat(sql).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findCountDifferentQueriesBit() {
|
||||
DB.getDefault().getPluginApi().getServerCacheManager().clearAll();
|
||||
differentFindCount(q->q.bitwiseAny("id",1), q->q.bitwiseAny("id",0));
|
||||
differentFindCount(q->q.bitwiseAll("id",1), q->q.bitwiseAll("id",0));
|
||||
// differentFindCount(q->q.bitwiseNot("id",1), q->q.bitwiseNot("id",0)); NOT 1 == AND 1 = 0
|
||||
differentFindCount(q->q.bitwiseAnd("id",1, 0), q->q.bitwiseAnd("id",1, 1));
|
||||
|
||||
differentFindCount(q->q.bitwiseAnd("id",2, 0), q->q.bitwiseAnd("id",4, 0));
|
||||
differentFindCount(q->q.bitwiseAnd("id",2, 1), q->q.bitwiseAnd("id",4, 1));
|
||||
// Will produce hash collision
|
||||
differentFindCount(q->q.bitwiseAnd("id",10, 0), q->q.bitwiseAnd("id",0, 928210));
|
||||
|
||||
}
|
||||
|
||||
void differentFindCount(Consumer<ExpressionList<EColAB>> q0, Consumer<ExpressionList<EColAB>> q1) {
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
ExpressionList<EColAB> el0 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where();
|
||||
q0.accept(el0);
|
||||
el0.findCount();
|
||||
|
||||
ExpressionList<EColAB> el1 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where();
|
||||
q1.accept(el1);
|
||||
el1.findCount();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
assertThat(sql).hasSize(2); // different queries
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,16 +16,19 @@ import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.changelog.ChangeSet;
|
||||
import io.ebean.event.changelog.ChangeType;
|
||||
import io.ebean.event.changelog.TxnState;
|
||||
import io.ebeantest.LoggedSql;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.EBasicChangeLog;
|
||||
import org.tests.model.json.PlainBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestChangeLog extends BaseTestCase {
|
||||
|
||||
@@ -130,6 +133,49 @@ public class TestChangeLog extends BaseTestCase {
|
||||
assertThat(change.getEvent()).isEqualTo(ChangeType.DELETE);
|
||||
assertThat(change.getData()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithJsonMutationDetection() {
|
||||
|
||||
EBasicChangeLog bean = new EBasicChangeLog();
|
||||
bean.setName(null);
|
||||
bean.setShortDescription("hello");
|
||||
PlainBean jsonBean = new PlainBean();
|
||||
bean.setPlainBean(jsonBean);
|
||||
jsonBean.setName("A");
|
||||
server.save(bean);
|
||||
|
||||
BeanChange change = firstChange();
|
||||
assertThat(change.getEvent()).isEqualTo(ChangeType.INSERT);
|
||||
|
||||
jsonBean.setName("B");
|
||||
LoggedSql.start();
|
||||
server.save(bean);
|
||||
assertThat(LoggedSql.stop()).isNotEmpty();
|
||||
|
||||
change = firstChange();
|
||||
assertThat(change.getEvent()).isEqualTo(ChangeType.UPDATE);
|
||||
assertThat(change.getData()).contains("\"plainBean\":{\"name\":\"B\"");
|
||||
assertThat(change.getOldData()).contains("\"plainBean\":{\"name\":\"A\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMutationWithCache() throws Exception {
|
||||
EBasicChangeLog bean = new EBasicChangeLog();
|
||||
bean.setName("Name1");
|
||||
bean.setPlainBean(new PlainBean("foo", 42));
|
||||
server.save(bean);
|
||||
BeanChange change = firstChange();
|
||||
assertThat(change.getData()).contains("\"plainBean\"");
|
||||
|
||||
server.find(EBasicChangeLog.class, bean.getId()); // load cache
|
||||
bean = server.find(EBasicChangeLog.class, bean.getId()); // hit cache
|
||||
bean.setShortDescription("Desc");
|
||||
server.save(bean);
|
||||
|
||||
change = firstChange();
|
||||
assertThat(change.getData()).doesNotContain("\"plainBean\"");
|
||||
}
|
||||
|
||||
private Database createServer() {
|
||||
|
||||
|
||||
@@ -1,21 +1,48 @@
|
||||
package org.tests.json;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.BeanState;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.ValuePair;
|
||||
import io.ebean.event.BeanPersistAdapter;
|
||||
import io.ebean.event.BeanPersistRequest;
|
||||
import io.ebeantest.LoggedSql;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.json.EBasicJsonJackson3;
|
||||
import org.tests.model.json.EBasicJsonList;
|
||||
import org.tests.model.json.EBasicJsonMulti;
|
||||
import org.tests.model.json.PlainBean;
|
||||
import org.tests.model.json.PlainBeanDirtyAware;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestDbJson_Jackson3 extends BaseTestCase {
|
||||
|
||||
public static class EBasicJsonListPersistController extends BeanPersistAdapter {
|
||||
|
||||
private static Map<String, ValuePair> updatedValues;
|
||||
|
||||
@Override
|
||||
public boolean isRegisterFor(Class<?> cls) {
|
||||
return EBasicJsonList.class.isAssignableFrom(cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preInsert(BeanPersistRequest<?> request) {
|
||||
updatedValues = request.getUpdatedValues();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preUpdate(BeanPersistRequest<?> request) {
|
||||
updatedValues = request.getUpdatedValues();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void updateIncludesJsonColumn_when_explicit_isMarkedDirty() {
|
||||
|
||||
@@ -24,6 +51,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase {
|
||||
EBasicJsonJackson3 bean = new EBasicJsonJackson3();
|
||||
bean.setName("b1");
|
||||
bean.setPlainValue(contentBean);
|
||||
bean.setPlainValue2(contentBean);
|
||||
|
||||
bean.save();
|
||||
|
||||
@@ -32,20 +60,15 @@ public class TestDbJson_Jackson3 extends BaseTestCase {
|
||||
|
||||
LoggedSql.start();
|
||||
found.save();
|
||||
|
||||
List<String> sql = LoggedSql.collect();
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set name=?, version=? where id=? and version=?");
|
||||
expectedSql(0, "update ebasic_json_jackson3 set name=?, version=? where id=? and version=?");
|
||||
|
||||
found.setName("b1-mod2");
|
||||
found.getPlainValue().setName("b");
|
||||
found.getPlainValue().setMarkedDirty(true);
|
||||
// found.getPlainValue().setMarkedDirty(true); // Irrelevant for SOURCE or HASH based mutation detection
|
||||
|
||||
found.save();
|
||||
|
||||
sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set name=?, plain_value=?, version=? where id=? and version=?");
|
||||
expectedSql(0, "update ebasic_json_jackson3 set name=?, plain_value=?, version=? where id=? and version=?");
|
||||
LoggedSql.stop();
|
||||
|
||||
final EBasicJsonJackson3 found2 = DB.find(EBasicJsonJackson3.class, bean.getId());
|
||||
|
||||
@@ -69,11 +92,153 @@ public class TestDbJson_Jackson3 extends BaseTestCase {
|
||||
found.setName("p1-mod");
|
||||
found.setBeanList(null);
|
||||
|
||||
BeanState state = DB.getBeanState(found);
|
||||
assertThat(state.getChangedProps()).containsExactlyInAnyOrder("name", "beanList");
|
||||
|
||||
ValuePair pair = state.getDirtyValues().get("name");
|
||||
assertThat(pair.getNewValue()).isEqualTo("p1-mod");
|
||||
assertThat(pair.getOldValue()).isEqualTo("p1");
|
||||
|
||||
pair = state.getDirtyValues().get("beanList");
|
||||
assertThat(pair.getNewValue()).isEqualTo(null);
|
||||
assertThat((List<PlainBean>)pair.getOldValue()).hasSize(1)
|
||||
.extracting(PlainBean::getName).containsExactly("a");
|
||||
|
||||
|
||||
LoggedSql.start();
|
||||
DB.save(found);
|
||||
|
||||
final List<String> sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, plain_bean=?, version=? where id=?");
|
||||
// plain_bean=?, no longer included with MD5 dirty detection
|
||||
expectedSql(0, "update ebasic_json_list set name=?, bean_list=?, version=? where id=?");
|
||||
|
||||
assertThat(EBasicJsonListPersistController.updatedValues.entrySet())
|
||||
.extracting(Map.Entry::toString)
|
||||
.containsExactlyInAnyOrder("beanList=null,[name:a]","name=p1-mod,p1","version=2,1");
|
||||
|
||||
assertThat(DB.getBeanState(found).isDirty()).isFalse();
|
||||
|
||||
found.getPlainBean().setName("b");
|
||||
assertThat(DB.getBeanState(found).isDirty()).isTrue();
|
||||
|
||||
state = DB.getBeanState(found);
|
||||
assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainBean");
|
||||
pair = state.getDirtyValues().get("plainBean");
|
||||
assertThat(pair.getNewValue()).hasToString("name:b");
|
||||
assertThat(pair.getOldValue()).hasToString("name:a");
|
||||
|
||||
|
||||
LoggedSql.start();
|
||||
DB.save(found);
|
||||
|
||||
// plain_bean=?, no longer included with MD5 dirty detection
|
||||
expectedSql(0, "update ebasic_json_list set plain_bean=?, version=? where id=?");
|
||||
|
||||
assertThat(EBasicJsonListPersistController.updatedValues.entrySet())
|
||||
.extracting(Map.Entry::toString)
|
||||
.containsExactlyInAnyOrder("plainBean=name:b,name:a", "version=3,2");
|
||||
|
||||
LoggedSql.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateIncludesJsonColumn_when_list_loadedAndNotDirtyAware() {
|
||||
|
||||
PlainBean contentBean = new PlainBean("a", 42);
|
||||
EBasicJsonList bean = new EBasicJsonList();
|
||||
bean.setName("p1");
|
||||
bean.setPlainBean(contentBean);
|
||||
bean.setBeanList(Arrays.asList(contentBean));
|
||||
|
||||
DB.save(bean);
|
||||
final EBasicJsonList found = DB.find(EBasicJsonList.class, bean.getId());
|
||||
found.getBeanList().get(0).setName("p1-mod");
|
||||
|
||||
BeanState state = DB.getBeanState(found);
|
||||
assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void update_with_differentDbJsonSettings() {
|
||||
PlainBeanDirtyAware contentBean1 = new PlainBeanDirtyAware("x", 42);
|
||||
PlainBeanDirtyAware contentBean2 = new PlainBeanDirtyAware("y", 43);
|
||||
PlainBeanDirtyAware contentBean3 = new PlainBeanDirtyAware("z", 44);
|
||||
|
||||
EBasicJsonJackson3 bean = new EBasicJsonJackson3();
|
||||
bean.setName("b1");
|
||||
bean.setPlainValue(contentBean1);
|
||||
bean.setPlainValue2(contentBean2);
|
||||
bean.setPlainValue3(contentBean3);
|
||||
|
||||
BeanState state = DB.getBeanState(bean);
|
||||
// a new bean is not considered as dirty (thus have no changed props)
|
||||
assertThat(state.isDirty()).isFalse();
|
||||
assertThat(state.isNewOrDirty()).isTrue();
|
||||
assertThat(state.getChangedProps()).isEmpty();
|
||||
|
||||
bean.save();
|
||||
|
||||
bean = DB.find(EBasicJsonJackson3.class, bean.getId());
|
||||
state = DB.getBeanState(bean);
|
||||
// a fresh loaded bean is also not considered as dirty
|
||||
assertThat(state.isDirty()).isFalse();
|
||||
assertThat(state.isNewOrDirty()).isFalse();
|
||||
assertThat(state.getChangedProps()).isEmpty();
|
||||
|
||||
bean.getPlainValue().setName("a"); // has SOURCE
|
||||
|
||||
assertThat(state.isDirty()).isTrue();
|
||||
assertThat(state.getChangedProps()).containsExactly("plainValue");
|
||||
|
||||
bean.getPlainValue2().setName("b");
|
||||
assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainValue", "plainValue2");
|
||||
|
||||
bean.getPlainValue3().setName("c"); // has mutationDetection = NONE
|
||||
|
||||
Map<String, ValuePair> dirtyValues = state.getDirtyValues();
|
||||
assertThat(dirtyValues).hasSize(2).containsKeys("plainValue", "plainValue2");
|
||||
|
||||
assertThat(dirtyValues.get("plainValue")).hasToString("name:a,name:x"); // SOURCE -> origValue present
|
||||
assertThat(dirtyValues.get("plainValue2")).hasToString("name:b,null"); // without SOURCE no origValue present
|
||||
|
||||
LoggedSql.start();
|
||||
bean.save();
|
||||
expectedSql(0, "update ebasic_json_jackson3 set plain_value=?, plain_value2=?, version=? where id=?");
|
||||
|
||||
bean = DB.find(EBasicJsonJackson3.class, bean.getId());
|
||||
LoggedSql.collect(); // ignore the select
|
||||
assertThat(bean.getPlainValue().getName()).isEqualTo("a");
|
||||
assertThat(bean.getPlainValue2().getName()).isEqualTo("b");
|
||||
assertThat(bean.getPlainValue3().getName()).isEqualTo("z"); // value is not updated
|
||||
|
||||
bean.getPlainValue3().setName("c");
|
||||
bean.getPlainValue3().setMarkedDirty(true); // This is ignored because it is MutationDetection.NONE
|
||||
bean.save();
|
||||
// no update as plainValue3 has MutationDetection.NONE (ModifyAwareType = NONE isn't an expected combination to me)
|
||||
assertThat(LoggedSql.collect()).isEmpty();
|
||||
|
||||
bean.getPlainValue2().setName("b2"); // effectively HASH mode mutation detection
|
||||
bean.save();
|
||||
expectedSql(0, "update ebasic_json_jackson3 set plain_value2=?, version=? where id=? and version=?");
|
||||
|
||||
LoggedSql.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void push_pop_test() {
|
||||
|
||||
EBasicJsonMulti bean = new EBasicJsonMulti();
|
||||
bean.setPlainValue2(new PlainBeanDirtyAware("x", 42));
|
||||
bean.save();
|
||||
|
||||
bean = DB.find(EBasicJsonMulti.class, bean.getId());
|
||||
bean.setPlainValue1(null); // already null
|
||||
bean.setPlainValue2(null);
|
||||
bean.setPlainValue3(null); // already null
|
||||
BeanState state = DB.getBeanState(bean);
|
||||
assertThat(state.getDirtyValues()).hasSize(1).containsKey("plainValue2");
|
||||
}
|
||||
|
||||
private void expectedSql(int i, String s) {
|
||||
assertThat(LoggedSql.collect().get(i)).contains(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,10 +76,11 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
update_when_dirty();
|
||||
update_when_dirty_flags();
|
||||
update_when_dirty_SetListMap();
|
||||
|
||||
DB.delete(found);
|
||||
}
|
||||
|
||||
//@Test//(dependsOnMethods = "insert")
|
||||
public void json_parse_format() {
|
||||
private void json_parse_format() {
|
||||
|
||||
String asJson = DB.json().toJson(found);
|
||||
assertThat(asJson).contains("\"tags\":[\"one\",\"two\"]");
|
||||
@@ -104,8 +105,7 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
assertThat(fromJson.getBeanMap()).hasSize(2);
|
||||
}
|
||||
|
||||
//@Test//(dependsOnMethods = "insert")
|
||||
public void update_when_notDirty() {
|
||||
private void update_when_notDirty() {
|
||||
|
||||
found.setName("mod");
|
||||
LoggedSqlCollector.start();
|
||||
@@ -113,10 +113,11 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// we don't update the phone numbers (as they are not dirty)
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set name=?, plain_bean=?, version=? where");
|
||||
// plain_bean=?, no longer included with MD5 dirty detection
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set name=?, version=? where");
|
||||
}
|
||||
|
||||
public void update_when_dirty() {
|
||||
private void update_when_dirty() {
|
||||
|
||||
//found.setName("modAgain");
|
||||
found.getTags().add("three");
|
||||
@@ -126,10 +127,11 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// we don't update the phone numbers (as they are not dirty)
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, tags=?, version=? where id=? and version=?");
|
||||
// plain_bean=? not included using MD5 dirty detection
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set tags=?, version=? where id=? and version=?");
|
||||
}
|
||||
|
||||
public void update_when_dirty_flags() {
|
||||
private void update_when_dirty_flags() {
|
||||
|
||||
//found.setName("modAgain");
|
||||
found.getFlags().remove(42L);
|
||||
@@ -139,10 +141,11 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// we don't update the phone numbers (as they are not dirty)
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, flags=?, version=? where id=? and version=?;");
|
||||
// plain_bean=? not included with MD5 dirty detection
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set flags=?, version=? where id=? and version=?;");
|
||||
}
|
||||
|
||||
public void update_when_dirty_SetListMap() {
|
||||
private void update_when_dirty_SetListMap() {
|
||||
|
||||
//found.setName("modAgain");
|
||||
found.getBeanSet().clear();
|
||||
@@ -154,7 +157,8 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
|
||||
// we don't update the phone numbers (as they are not dirty)
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set beans=?, bean_list=?, bean_map=?, plain_bean=?, version=? where id=? and version=?");
|
||||
// plain_bean=? not included with MD5 dirty detection
|
||||
assertSql(sql.get(0)).contains("update ebasic_json_list set beans=?, bean_list=?, bean_map=?, version=? where id=? and version=?");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -221,4 +225,19 @@ public class TestDbJson_List extends BaseTestCase {
|
||||
|
||||
DB.delete(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullToEmpty() {
|
||||
EBasicJsonList bean = new EBasicJsonList();
|
||||
bean.setFlags(null);
|
||||
bean.setTags(null);
|
||||
bean.setBeanMap(null);
|
||||
DB.save(bean);
|
||||
|
||||
bean = DB.find(EBasicJsonList.class).setId(bean.getId()).findOne();
|
||||
|
||||
assertThat(bean.getFlags()).isEmpty();
|
||||
assertThat(bean.getTags()).isEmpty();
|
||||
assertThat(bean.getBeanMap()).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.tests.json;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.json.EBasicOldValue;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestJsonNullValues extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testSetToNull() {
|
||||
EBasicOldValue bean = new EBasicOldValue();
|
||||
DB.save(bean);
|
||||
bean = DB.find(EBasicOldValue.class, bean.getId());
|
||||
|
||||
bean.setStringList(null);
|
||||
bean.setStringSet(null);
|
||||
bean.setObjectMap(null);
|
||||
bean.setLongList(null);
|
||||
bean.setLongSet(null);
|
||||
bean.setLongMap(null);
|
||||
bean.setIntList(null);
|
||||
bean.setIntSet(null);
|
||||
bean.setIntMap(null);
|
||||
|
||||
DB.save(bean);
|
||||
bean = DB.find(EBasicOldValue.class, bean.getId());
|
||||
|
||||
assertThat(bean.getStringList()).isEmpty();
|
||||
assertThat(bean.getStringSet()).isEmpty();
|
||||
assertThat(bean.getObjectMap()).isEmpty();
|
||||
assertThat(bean.getLongList()).isEmpty();
|
||||
assertThat(bean.getLongSet()).isEmpty();
|
||||
assertThat(bean.getLongMap()).isEmpty();
|
||||
assertThat(bean.getIntList()).isEmpty();
|
||||
assertThat(bean.getIntSet()).isEmpty();
|
||||
assertThat(bean.getIntMap()).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.tests.json;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.json.EBasicOldValue;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TestOldValue extends BaseTestCase {
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Test
|
||||
public void testDbJsonOldValue() throws Exception {
|
||||
EBasicOldValue bean = new EBasicOldValue();
|
||||
JsonNodeFactory jnf = new JsonNodeFactory(false);
|
||||
|
||||
bean.getStringList().add("sl1");
|
||||
bean.getStringSet().add("ss1");
|
||||
bean.getObjectMap().put("sk1","sm1");
|
||||
bean.getLongList().add(1L);
|
||||
bean.getLongSet().add(1001L);
|
||||
bean.getLongMap().put("lk1",2001L);
|
||||
bean.getIntList().add(2);
|
||||
bean.getIntSet().add(1002);
|
||||
bean.getIntMap().put("ik1",2002);
|
||||
|
||||
bean.setJsonNode(jnf.arrayNode().add("Foo"));
|
||||
|
||||
DB.save(bean);
|
||||
bean = DB.find(EBasicOldValue.class, bean.getId());
|
||||
|
||||
bean.getStringList().add("sl2");
|
||||
bean.getStringSet().add("ss2");
|
||||
bean.getObjectMap().put("sk2","sm2");
|
||||
bean.getLongList().add(5L);
|
||||
bean.getLongSet().add(1005L);
|
||||
bean.getLongMap().put("lk2",2005L);
|
||||
bean.getIntList().add(6);
|
||||
bean.getIntSet().add(1006);
|
||||
bean.getIntMap().put("ik2",2006);
|
||||
((ArrayNode)bean.getJsonNode()).add("Bar");
|
||||
|
||||
Map<String, ValuePair> dirty = DB.getBeanState(bean).getDirtyValues();
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
softly.assertThat(dirty).hasSize(10);
|
||||
|
||||
softly.assertThat((List)dirty.get("stringList").getOldValue()).containsExactly("sl1");
|
||||
softly.assertThat((List)dirty.get("stringList").getNewValue()).containsExactly("sl1", "sl2");
|
||||
softly.assertThat((List)dirty.get("longList").getOldValue()).containsExactly(1L);
|
||||
softly.assertThat((List)dirty.get("longList").getNewValue()).containsExactly(1L, 5L);
|
||||
softly.assertThat((List)dirty.get("intList").getOldValue()).containsExactly(2);
|
||||
softly.assertThat((List)dirty.get("intList").getNewValue()).containsExactly(2, 6);
|
||||
|
||||
softly.assertThat((Set)dirty.get("stringSet").getOldValue()).containsExactly("ss1");
|
||||
softly.assertThat((Set)dirty.get("stringSet").getNewValue()).containsExactly("ss1", "ss2");
|
||||
softly.assertThat((Set)dirty.get("longSet").getOldValue()).containsExactly(1001L);
|
||||
softly.assertThat((Set)dirty.get("longSet").getNewValue()).containsExactly(1001L, 1005L);
|
||||
softly.assertThat((Set)dirty.get("intSet").getOldValue()).containsExactly(1002);
|
||||
softly.assertThat((Set)dirty.get("intSet").getNewValue()).containsExactly(1002, 1006);
|
||||
|
||||
softly.assertThat((Map)dirty.get("objectMap").getOldValue()).containsEntry("sk1","sm1").hasSize(1);
|
||||
softly.assertThat((Map)dirty.get("objectMap").getNewValue()).containsEntry("sk1","sm1").containsEntry("sk2","sm2").hasSize(2);
|
||||
softly.assertThat((Map)dirty.get("longMap").getOldValue()).containsEntry("lk1",2001L).hasSize(1);
|
||||
softly.assertThat((Map)dirty.get("longMap").getNewValue()).containsEntry("lk1",2001L).containsEntry("lk2",2005L).hasSize(2);
|
||||
softly.assertThat((Map)dirty.get("intMap").getOldValue()).containsEntry("ik1",2002).hasSize(1);
|
||||
softly.assertThat((Map)dirty.get("intMap").getNewValue()).containsEntry("ik1",2002).containsEntry("ik2",2006).hasSize(2);
|
||||
|
||||
softly.assertThat((ArrayNode)dirty.get("jsonNode").getOldValue()).hasToString("[\"Foo\"]");
|
||||
softly.assertThat((ArrayNode)dirty.get("jsonNode").getNewValue()).hasToString("[\"Foo\",\"Bar\"]");
|
||||
|
||||
softly.assertAll();
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Test
|
||||
@Ignore("Old value detection does not work for @DbArray")
|
||||
public void testDbArrayOldValue() throws Exception {
|
||||
EBasicOldValue bean = new EBasicOldValue();
|
||||
|
||||
bean.getStringArr().add("sa1");
|
||||
|
||||
|
||||
DB.save(bean);
|
||||
bean = DB.find(EBasicOldValue.class, bean.getId());
|
||||
|
||||
bean.getStringArr().add("sa2");
|
||||
|
||||
|
||||
|
||||
Map<String, ValuePair> dirty = DB.getBeanState(bean).getDirtyValues();
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
softly.assertThat(dirty).hasSize(1);
|
||||
|
||||
softly.assertThat((List)dirty.get("stringArr").getOldValue()).containsExactly("sa1");
|
||||
softly.assertThat((List)dirty.get("stringArr").getNewValue()).containsExactly("sa1", "sa2");
|
||||
|
||||
softly.assertAll();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class TestM2mDeleteObject extends BaseTestCase {
|
||||
|
||||
List<MetaTimedMetric> sqlMetrics = sqlMetrics();
|
||||
assertThat(sqlMetrics).hasSize(1);
|
||||
assertThat(sqlMetrics.get(0).getName()).isEqualTo("orm.update.deleteAllPermissions");
|
||||
assertThat(sqlMetrics.get(0).name()).isEqualTo("orm.update.deleteAllPermissions");
|
||||
|
||||
Tenant t = new Tenant("tenant");
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.tests.model.basic;
|
||||
|
||||
import io.ebean.annotation.Cache;
|
||||
import io.ebean.annotation.ChangeLog;
|
||||
import io.ebean.annotation.DbJson;
|
||||
import io.ebean.annotation.ReadAudit;
|
||||
import io.ebean.annotation.WhenCreated;
|
||||
import io.ebean.annotation.WhenModified;
|
||||
@@ -12,11 +13,16 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.tests.model.json.PlainBean;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.SOURCE;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Cache(enableQueryCache = true)
|
||||
@ReadAudit
|
||||
@ChangeLog(updatesThatInclude = {"name", "shortDescription"})
|
||||
@ChangeLog(updatesThatInclude = {"name", "shortDescription", "plainBean"})
|
||||
@Entity
|
||||
public class EBasicChangeLog {
|
||||
|
||||
@@ -46,6 +52,9 @@ public class EBasicChangeLog {
|
||||
|
||||
@Version
|
||||
Long version;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = SOURCE) // such that we can rebuild old values
|
||||
PlainBean plainBean;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
@@ -118,4 +127,12 @@ public class EBasicChangeLog {
|
||||
public void setVersion(Long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public PlainBean getPlainBean() {
|
||||
return plainBean;
|
||||
}
|
||||
|
||||
public void setPlainBean(PlainBean plainBean) {
|
||||
this.plainBean = plainBean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ public class CustomerFinder extends Finder<Integer, Customer> {
|
||||
}
|
||||
|
||||
public List<Customer> byNameStatus(String nameStartsWith, Customer.Status status) {
|
||||
|
||||
return query("where status = :status and name istartsWith :name order by name")
|
||||
.setParameter("status", status)
|
||||
.setParameter("name", nameStartsWith)
|
||||
@@ -45,7 +44,6 @@ public class CustomerFinder extends Finder<Integer, Customer> {
|
||||
}
|
||||
|
||||
public List<String> namesStartingWith(String name) {
|
||||
|
||||
return nativeSql("select name from o_customer where name like ? order by name")
|
||||
.setParameter(name + "%")
|
||||
.findSingleAttributeList();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.tests.model.bridge;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@Embeddable
|
||||
public class BDManyId {
|
||||
|
||||
private final UUID siteId;
|
||||
private final UUID userId;
|
||||
private final String name;
|
||||
|
||||
public BDManyId(UUID siteId, UUID userId, String name) {
|
||||
this.siteId = siteId;
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BDManyId bdManyId = (BDManyId) o;
|
||||
return siteId.equals(bdManyId.siteId) && userId.equals(bdManyId.userId) && name.equals(bdManyId.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(siteId, userId, name);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.tests.model.bridge;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Version;
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@@ -18,6 +16,10 @@ public class BSiteUserD {
|
||||
|
||||
private BAccessLevel accessLevel;
|
||||
|
||||
@OneToMany(cascade = CascadeType.PERSIST)
|
||||
@JoinColumns({@JoinColumn(name="site_id", referencedColumnName = "site_id"), @JoinColumn(name="user_id", referencedColumnName = "user_id")})
|
||||
private List<BSiteUserDMany> children;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
@@ -58,4 +60,12 @@ public class BSiteUserD {
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public List<BSiteUserDMany> children() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<BSiteUserDMany> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.tests.model.bridge;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@IdClass(BDManyId.class)
|
||||
public class BSiteUserDMany {
|
||||
|
||||
@Id
|
||||
private UUID siteId;
|
||||
@Id
|
||||
private UUID userId;
|
||||
@Id
|
||||
String name;
|
||||
|
||||
String many;
|
||||
|
||||
@Version
|
||||
long version;
|
||||
|
||||
public UUID siteId() {
|
||||
return siteId;
|
||||
}
|
||||
|
||||
public BSiteUserDMany siteId(UUID siteId) {
|
||||
this.siteId = siteId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UUID userId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public BSiteUserDMany userId(UUID userId) {
|
||||
this.userId = userId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public BSiteUserDMany name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String many() {
|
||||
return many;
|
||||
}
|
||||
|
||||
public void setMany(String many) {
|
||||
this.many = many;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,24 @@ public class TestIdClassScalar extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fetchMany() {
|
||||
UUID siteId = UUID.randomUUID();
|
||||
UUID userId = UUID.randomUUID();
|
||||
|
||||
BSiteUserD access = new BSiteUserD(BAccessLevel.ONE, siteId, userId);
|
||||
DB.save(access);
|
||||
|
||||
final List<BSiteUserD> found = DB.find(BSiteUserD.class)
|
||||
.fetch("children")
|
||||
.where().eq("siteId", siteId)
|
||||
.findList();
|
||||
|
||||
assertThat(found).hasSize(1);
|
||||
|
||||
DB.delete(BSiteUserD.class, new BEmbId(siteId, userId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertBatch() {
|
||||
UUID siteId = UUID.randomUUID();
|
||||
@@ -114,7 +132,7 @@ public class TestIdClassScalar extends BaseTestCase {
|
||||
sql = LoggedSqlCollector.stop();
|
||||
|
||||
assertThat(sql).hasSize(2);
|
||||
assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.site_id, t0.user_id, t0.access_level, t0.version from bsite_user_d t0 where t0.site_id = ? and t0.user_id = ?");
|
||||
assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.site_id, t0.user_id, t0.access_level, t0.version from bsite_user_d t0 where t0.site_id=? and t0.user_id=?");
|
||||
assertSql(sql.get(1)).contains("update bsite_user_d set access_level=?, version=? where site_id=? and user_id=? and version=?");
|
||||
}
|
||||
|
||||
@@ -160,7 +178,7 @@ public class TestIdClassScalar extends BaseTestCase {
|
||||
sql = LoggedSqlCollector.stop();
|
||||
|
||||
assertThat(sql).hasSize(2);
|
||||
assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.access_level, t0.site_id, t0.user_id from bsite_user_e t0 where t0.site_id = ? and t0.user_id = ?");
|
||||
assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.access_level, t0.site_id, t0.user_id from bsite_user_e t0 where t0.site_id=? and t0.user_id=?");
|
||||
assertSql(sql.get(1)).contains("update bsite_user_e set access_level=? where site_id=? and user_id=?");
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package org.tests.model.embedded;
|
||||
|
||||
import io.ebean.annotation.DbJson;
|
||||
import org.tests.model.json.PlainBean;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import java.util.Map;
|
||||
|
||||
@Embeddable
|
||||
public class EAddress {
|
||||
@@ -18,6 +22,12 @@ public class EAddress {
|
||||
@Enumerated(EnumType.STRING)
|
||||
EAddressStatus status;
|
||||
|
||||
@DbJson
|
||||
PlainBean jbean;
|
||||
|
||||
@DbJson
|
||||
Map<String, Object> jraw;
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
@@ -42,6 +52,22 @@ public class EAddress {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public PlainBean getJbean() {
|
||||
return jbean;
|
||||
}
|
||||
|
||||
public void setJbean(PlainBean jbean) {
|
||||
this.jbean = jbean;
|
||||
}
|
||||
|
||||
public Map<String, Object> getJraw() {
|
||||
return jraw;
|
||||
}
|
||||
|
||||
public void setJraw(Map<String, Object> jraw) {
|
||||
this.jraw = jraw;
|
||||
}
|
||||
|
||||
public EAddressStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ public class EPerson {
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "city", column = @Column(name = "addr_city")),
|
||||
@AttributeOverride(name = "status", column = @Column(name = "addr_status"))
|
||||
@AttributeOverride(name = "status", column = @Column(name = "addr_status")),
|
||||
@AttributeOverride(name = "jbean", column = @Column(name = "addr_jbean"))
|
||||
})
|
||||
EAddress address;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class TestHistoryEmbeddedId extends BaseTestCase {
|
||||
assertThat(namePair.getOldValue()).isEqualTo("ten");
|
||||
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("from hembi_bean_with_history t0 where t0.part = ? and t0.brand = ?");
|
||||
assertThat(sql.get(0)).contains("from hembi_bean_with_history t0 where t0.part=? and t0.brand=?");
|
||||
if (isH2()) {
|
||||
assertThat(sql.get(0)).contains("order by t0.sys_period_start desc");
|
||||
} else if (isPostgres()) {
|
||||
|
||||
@@ -2,11 +2,15 @@ package org.tests.model.json;
|
||||
|
||||
import io.ebean.Model;
|
||||
import io.ebean.annotation.DbJson;
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.NONE;
|
||||
import static io.ebean.annotation.MutationDetection.SOURCE;
|
||||
|
||||
@Entity
|
||||
public class EBasicJsonJackson3 extends Model {
|
||||
|
||||
@@ -15,9 +19,15 @@ public class EBasicJsonJackson3 extends Model {
|
||||
|
||||
String name;
|
||||
|
||||
@DbJson(length = 500)
|
||||
@DbJson(length = 500, mutationDetection = SOURCE)
|
||||
PlainBeanDirtyAware plainValue;
|
||||
|
||||
@DbJson(length = 500)
|
||||
PlainBeanDirtyAware plainValue2;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = NONE)
|
||||
PlainBeanDirtyAware plainValue3;
|
||||
|
||||
@Version
|
||||
long version;
|
||||
|
||||
@@ -45,6 +55,22 @@ public class EBasicJsonJackson3 extends Model {
|
||||
this.plainValue = plainValue;
|
||||
}
|
||||
|
||||
public PlainBeanDirtyAware getPlainValue2() {
|
||||
return plainValue2;
|
||||
}
|
||||
|
||||
public void setPlainValue2(PlainBeanDirtyAware plainValue2) {
|
||||
this.plainValue2 = plainValue2;
|
||||
}
|
||||
|
||||
public PlainBeanDirtyAware getPlainValue3() {
|
||||
return plainValue3;
|
||||
}
|
||||
|
||||
public void setPlainValue3(PlainBeanDirtyAware plainValue3) {
|
||||
this.plainValue3 = plainValue3;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,10 @@ import io.ebean.annotation.DbJsonType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.HASH;
|
||||
import static io.ebean.annotation.MutationDetection.SOURCE;
|
||||
|
||||
@Entity
|
||||
public class EBasicJsonList {
|
||||
@@ -22,16 +20,17 @@ public class EBasicJsonList {
|
||||
|
||||
String name;
|
||||
|
||||
// @JsonDeserialize(as=LinkedHashSet.class)
|
||||
@DbJson(length = 700, name = "beans")
|
||||
Set<PlainBean> beanSet;
|
||||
|
||||
@DbJsonB
|
||||
@DbJsonB(mutationDetection = HASH)
|
||||
List<PlainBean> beanList;
|
||||
|
||||
@DbJson(length = 700)
|
||||
Map<String, PlainBean> beanMap = new LinkedHashMap<>();
|
||||
|
||||
@DbJson(length = 500)
|
||||
@DbJson(length = 500, mutationDetection = SOURCE) // such that we can rebuild old values
|
||||
PlainBean plainBean;
|
||||
|
||||
@DbJson(length = 50)
|
||||
|
||||
@@ -20,7 +20,7 @@ public class EBasicJsonMapVarchar {
|
||||
String name;
|
||||
|
||||
@DbJson(storage = DbJsonType.VARCHAR)//, length = 2200)
|
||||
Map<String, Object> content;
|
||||
Map<String, Object> content;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.tests.model.json;
|
||||
|
||||
import io.ebean.Model;
|
||||
import io.ebean.annotation.DbJson;
|
||||
import io.ebean.annotation.MutationDetection;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.NONE;
|
||||
import static io.ebean.annotation.MutationDetection.SOURCE;
|
||||
|
||||
@Entity
|
||||
public class EBasicJsonMulti extends Model {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String name;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = SOURCE)
|
||||
PlainBeanDirtyAware plainValue1;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = SOURCE)
|
||||
PlainBeanDirtyAware plainValue2;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = SOURCE)
|
||||
PlainBeanDirtyAware plainValue3;
|
||||
|
||||
@Version
|
||||
long version;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public PlainBeanDirtyAware getPlainValue1() {
|
||||
return plainValue1;
|
||||
}
|
||||
|
||||
public void setPlainValue1(PlainBeanDirtyAware plainValue1) {
|
||||
this.plainValue1 = plainValue1;
|
||||
}
|
||||
|
||||
public PlainBeanDirtyAware getPlainValue2() {
|
||||
return plainValue2;
|
||||
}
|
||||
|
||||
public void setPlainValue2(PlainBeanDirtyAware plainValue2) {
|
||||
this.plainValue2 = plainValue2;
|
||||
}
|
||||
|
||||
public PlainBeanDirtyAware getPlainValue3() {
|
||||
return plainValue3;
|
||||
}
|
||||
|
||||
public void setPlainValue3(PlainBeanDirtyAware plainValue3) {
|
||||
this.plainValue3 = plainValue3;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package org.tests.model.json;
|
||||
|
||||
import io.ebean.annotation.DbArray;
|
||||
import io.ebean.annotation.DbJson;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.SOURCE;
|
||||
|
||||
@Entity
|
||||
public class EBasicOldValue {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String name;
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Set<String> stringSet = new LinkedHashSet<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Set<Long> longSet = new LinkedHashSet<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Set<Integer> intSet = new LinkedHashSet<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
List<String> stringList = new ArrayList<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
List<Long> longList = new ArrayList<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
List<Integer> intList = new ArrayList<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Map<String, Object> objectMap = new LinkedHashMap<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Map<String, Long> longMap = new LinkedHashMap<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
Map<String, Integer> intMap = new LinkedHashMap<>();
|
||||
|
||||
@DbJson(mutationDetection = SOURCE)
|
||||
JsonNode jsonNode;
|
||||
|
||||
@DbArray()
|
||||
List<String> stringArr = new ArrayList<>();
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Set<String> getStringSet() {
|
||||
return stringSet;
|
||||
}
|
||||
|
||||
public void setStringSet(Set<String> stringSet) {
|
||||
this.stringSet = stringSet;
|
||||
}
|
||||
|
||||
public Set<Long> getLongSet() {
|
||||
return longSet;
|
||||
}
|
||||
|
||||
public void setLongSet(Set<Long> longSet) {
|
||||
this.longSet = longSet;
|
||||
}
|
||||
|
||||
public Set<Integer> getIntSet() {
|
||||
return intSet;
|
||||
}
|
||||
|
||||
public void setIntSet(Set<Integer> intSet) {
|
||||
this.intSet = intSet;
|
||||
}
|
||||
|
||||
public List<String> getStringList() {
|
||||
return stringList;
|
||||
}
|
||||
|
||||
public void setStringList(List<String> stringList) {
|
||||
this.stringList = stringList;
|
||||
}
|
||||
|
||||
public List<Long> getLongList() {
|
||||
return longList;
|
||||
}
|
||||
|
||||
public void setLongList(List<Long> longList) {
|
||||
this.longList = longList;
|
||||
}
|
||||
|
||||
public List<Integer> getIntList() {
|
||||
return intList;
|
||||
}
|
||||
|
||||
public void setIntList(List<Integer> intList) {
|
||||
this.intList = intList;
|
||||
}
|
||||
|
||||
public Map<String, Object> getObjectMap() {
|
||||
return objectMap;
|
||||
}
|
||||
|
||||
public void setObjectMap(Map<String, Object> objectMap) {
|
||||
this.objectMap = objectMap;
|
||||
}
|
||||
|
||||
public Map<String, Long> getLongMap() {
|
||||
return longMap;
|
||||
}
|
||||
|
||||
public void setLongMap(Map<String, Long> longMap) {
|
||||
this.longMap = longMap;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getIntMap() {
|
||||
return intMap;
|
||||
}
|
||||
|
||||
public void setIntMap(Map<String, Integer> intMap) {
|
||||
this.intMap = intMap;
|
||||
}
|
||||
|
||||
public JsonNode getJsonNode() {
|
||||
return jsonNode;
|
||||
}
|
||||
|
||||
public void setJsonNode(JsonNode jsonNode) {
|
||||
this.jsonNode = jsonNode;
|
||||
}
|
||||
|
||||
public List<String> getStringArr() {
|
||||
return stringArr;
|
||||
}
|
||||
|
||||
public void setStringArr(List<String> stringArr) {
|
||||
this.stringArr = stringArr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.tests.model.json;
|
||||
|
||||
import io.ebean.annotation.DbJson;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import static io.ebean.annotation.MutationDetection.NONE;
|
||||
|
||||
@Entity
|
||||
public class EBasicPlain {
|
||||
|
||||
@Id
|
||||
long id;
|
||||
|
||||
String attr;
|
||||
|
||||
@DbJson(length = 500)
|
||||
PlainBean plainBean;
|
||||
|
||||
@DbJson(length = 500, mutationDetection = NONE) // only update when property set
|
||||
PlainBean plainBean2;
|
||||
|
||||
@Version
|
||||
long version;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAttr() {
|
||||
return attr;
|
||||
}
|
||||
|
||||
public void setAttr(String attr) {
|
||||
this.attr = attr;
|
||||
}
|
||||
|
||||
public PlainBean getPlainBean() {
|
||||
return plainBean;
|
||||
}
|
||||
|
||||
public void setPlainBean(PlainBean plainBean) {
|
||||
this.plainBean = plainBean;
|
||||
}
|
||||
|
||||
public PlainBean getPlainBean2() {
|
||||
return plainBean2;
|
||||
}
|
||||
|
||||
public void setPlainBean2(PlainBean plainBean2) {
|
||||
this.plainBean2 = plainBean2;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.tests.model.json;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebeantest.LoggedSql;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestJacksonPlainBean {
|
||||
|
||||
@Test
|
||||
public void insertNullStayNull() {
|
||||
|
||||
// insert with jackson beans as null
|
||||
EBasicPlain bean = new EBasicPlain();
|
||||
bean.setAttr("n0");
|
||||
DB.save(bean);
|
||||
|
||||
LoggedSql.start();
|
||||
bean.setAttr("n1");
|
||||
DB.save(bean);
|
||||
expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?");
|
||||
|
||||
bean.setPlainBean(new PlainBean("x", 1));
|
||||
DB.save(bean);
|
||||
expectedSql(0, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?");
|
||||
|
||||
final EBasicPlain found = DB.find(EBasicPlain.class, bean.getId());
|
||||
found.setAttr("n2");
|
||||
DB.save(found);
|
||||
expectedSql(1, "update ebasic_plain set attr=?, version=? where id=? and version=?");
|
||||
|
||||
LoggedSql.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertUpdate() {
|
||||
|
||||
DB.getDefault();
|
||||
LoggedSql.start();
|
||||
|
||||
PlainBean content = new PlainBean("foo", 42);
|
||||
EBasicPlain bean = new EBasicPlain();
|
||||
bean.setAttr("attr0");
|
||||
bean.setPlainBean(content);
|
||||
bean.setPlainBean2(new PlainBean("bar", 27));
|
||||
|
||||
DB.save(bean);
|
||||
expectedSql(0, "insert into ebasic_plain (attr, plain_bean, plain_bean2, version) values (?,?,?,?)");
|
||||
|
||||
// inserted plainBean has not been mutated
|
||||
bean.setAttr("attr1");
|
||||
DB.save(bean);
|
||||
expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?");
|
||||
|
||||
// inserted plainBean has now been mutated
|
||||
content.setName("notFoo");
|
||||
bean.setAttr("attr2");
|
||||
DB.save(bean);
|
||||
expectedSql(0, "update ebasic_plain set attr=?, plain_bean=?, version=? where id=? and version=?");
|
||||
|
||||
|
||||
final EBasicPlain found = DB.find(EBasicPlain.class, bean.getId());
|
||||
|
||||
// update mutating PlainBean only
|
||||
final PlainBean plainBean = found.getPlainBean();
|
||||
plainBean.setName("mod1");
|
||||
DB.save(found);
|
||||
expectedSql(1, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?");
|
||||
|
||||
// dirtyDetection = false, so not included in update
|
||||
found.getPlainBean2().setName("Modification Ignored");
|
||||
// dirtyDetection = true, mutation detected
|
||||
plainBean.setName("mod2");
|
||||
DB.save(found);
|
||||
expectedSql(0, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?");
|
||||
|
||||
// update bean, not mutating PlainBean
|
||||
found.setAttr("attr3");
|
||||
DB.save(found);
|
||||
expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?");
|
||||
|
||||
// dirtyDetection = false, set a new plainBean2 instance, included in update
|
||||
found.setPlainBean2(new PlainBean("bar", 27));
|
||||
DB.save(found);
|
||||
expectedSql(0, "update ebasic_plain set plain_bean2=?, version=? where id=? and version=?");
|
||||
|
||||
LoggedSql.stop();
|
||||
}
|
||||
|
||||
private void expectedSql(int i, String s) {
|
||||
assertThat(LoggedSql.collect().get(i)).contains(s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,20 +7,26 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ProfileLocationTest {
|
||||
|
||||
private static ProfileLocation loc = ProfileLocation.create(12, "foo");
|
||||
|
||||
private static ProfileLocation loc2 = ProfileLocation.create();
|
||||
private static final ProfileLocation loc = ProfileLocation.create(12, "foo");
|
||||
private static final ProfileLocation locB = ProfileLocation.create();
|
||||
private static final ProfileLocation loc2 = ProfileLocation.create();
|
||||
|
||||
private boolean doIt() {
|
||||
locB.obtain(); // simulate a location moving by line number only
|
||||
return loc.obtain();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_obtain() {
|
||||
assertThat(doIt()).isTrue();
|
||||
assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)");
|
||||
assertThat(loc.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:15)");
|
||||
assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:16)");
|
||||
assertThat(loc.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt");
|
||||
assertThat(loc.label()).isEqualTo("ProfileLocationTest.doIt");
|
||||
|
||||
// same hash even when the line number has changed
|
||||
assertThat(locB.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)");
|
||||
assertThat(locB.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt");
|
||||
assertThat(locB.label()).isEqualTo("ProfileLocationTest.doIt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -35,7 +41,7 @@ public class ProfileLocationTest {
|
||||
other.hashCode();
|
||||
|
||||
assertThat(loc2.label()).isEqualTo("ProfileLocationTest$Other.init");
|
||||
assertThat(loc2.location()).isEqualTo("ProfileLocationTest$Other.<init>(ProfileLocationTest.java:44)");
|
||||
assertThat(loc2.location()).isEqualTo("org.tests.profile.ProfileLocationTest$Other.<init>");
|
||||
}
|
||||
|
||||
static class Other {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.tests.query;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Query;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.CKeyParent;
|
||||
@@ -16,11 +16,11 @@ public class TestQueryAlias extends BaseTestCase {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<CKeyParent> sq = Ebean.createQuery(CKeyParent.class)
|
||||
Query<CKeyParent> sq = DB.createQuery(CKeyParent.class)
|
||||
.select("id.oneKey").alias("st0")
|
||||
.setAutoTune(false).where().query();
|
||||
|
||||
Query<CKeyParent> pq = Ebean.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query();
|
||||
Query<CKeyParent> pq = DB.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query();
|
||||
|
||||
pq.findList();
|
||||
|
||||
@@ -36,17 +36,36 @@ public class TestQueryAlias extends BaseTestCase {
|
||||
assertThat(sql).contains("ckey_parent myt0");
|
||||
assertThat(sql).contains("(myt0.one_key) in (select st0.one_key from ckey_parent st0)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithConcat() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<CKeyParent> sq = DB.createQuery(CKeyParent.class)
|
||||
.select("concat(id.oneKey,id.twoKey)").alias("st0")
|
||||
.setAutoTune(false).where().query();
|
||||
|
||||
Query<CKeyParent> pq = DB.find(CKeyParent.class).alias("myt0").where().in("concat(id.oneKey,id.twoKey)", sq).query();
|
||||
|
||||
pq.findList();
|
||||
|
||||
String sql = pq.getGeneratedSql();
|
||||
|
||||
assertThat(sql).contains("ckey_parent myt0");
|
||||
assertThat(sql).contains("(concat(myt0.one_key,myt0.two_key)) in (select concat(st0.one_key,st0.two_key) from ckey_parent st0)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotExists() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<CKeyParent> sq = Ebean.createQuery(CKeyParent.class)
|
||||
Query<CKeyParent> sq = DB.createQuery(CKeyParent.class)
|
||||
.select("id.oneKey").alias("st0")
|
||||
.setAutoTune(false).where().query();
|
||||
|
||||
Query<CKeyParent> pq = Ebean.find(CKeyParent.class).alias("myt0").where().notIn("id.oneKey", sq).query();
|
||||
Query<CKeyParent> pq = DB.find(CKeyParent.class).alias("myt0").where().notIn("id.oneKey", sq).query();
|
||||
|
||||
pq.findList();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.tests.query;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Query;
|
||||
import io.ebeantest.LoggedSql;
|
||||
import org.junit.Test;
|
||||
@@ -20,7 +20,7 @@ public class TestQueryExists extends BaseTestCase {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Order> query = Ebean.find(Order.class)
|
||||
Query<Order> query = DB.find(Order.class)
|
||||
.where().gt("id", 1)
|
||||
.query();
|
||||
|
||||
@@ -33,8 +33,8 @@ public class TestQueryExists extends BaseTestCase {
|
||||
assertThat(sql).contains("select t0.id from o_order t0 where t0.id > ? limit 1");
|
||||
}
|
||||
|
||||
assertThat(Ebean.find(Order.class).where().gt("id", 1).exists()).isTrue();
|
||||
assertThat(Ebean.find(Order.class).where().or().gt("id", 1).isNull("shipDate").exists()).isTrue();
|
||||
assertThat(DB.find(Order.class).where().gt("id", 1).exists()).isTrue();
|
||||
assertThat(DB.find(Order.class).where().or().gt("id", 1).isNull("shipDate").exists()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -42,13 +42,13 @@ public class TestQueryExists extends BaseTestCase {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Order> query = Ebean.find(Order.class)
|
||||
Query<Order> query = DB.find(Order.class)
|
||||
.where().raw("exists (select 1 from o_order_detail where order_id = t0.id)")
|
||||
.query();
|
||||
|
||||
List<Order> ordersThatHave = query.findList();
|
||||
|
||||
Query<Order> query2 = Ebean.find(Order.class)
|
||||
Query<Order> query2 = DB.find(Order.class)
|
||||
.where().raw("not exists (select 1 from o_order_detail where order_id = t0.id)")
|
||||
.query();
|
||||
|
||||
@@ -66,13 +66,13 @@ public class TestQueryExists extends BaseTestCase {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Customer> query = Ebean.find(Customer.class)
|
||||
Query<Customer> query = DB.find(Customer.class)
|
||||
.where().raw("exists (select 1 from contact where customer_id = t0.id)")
|
||||
.query();
|
||||
|
||||
List<Customer> customersWithContacts = query.findList();
|
||||
|
||||
Query<Customer> query2 = Ebean.find(Customer.class)
|
||||
Query<Customer> query2 = DB.find(Customer.class)
|
||||
.where().raw("not exists (select 1 FROM contact where customer_id = t0.id)")
|
||||
.query();
|
||||
|
||||
@@ -88,27 +88,27 @@ public class TestQueryExists extends BaseTestCase {
|
||||
public void testExists() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Order> subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query();
|
||||
Query<Order> subQuery = DB.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query();
|
||||
|
||||
Query<Customer> query = Ebean.find(Customer.class).alias("qt").where().exists(subQuery).query();
|
||||
Query<Customer> query = DB.find(Customer.class).alias("qt").where().exists(subQuery).query();
|
||||
|
||||
query.findList();
|
||||
String sql = query.getGeneratedSql();
|
||||
|
||||
assertThat(sql).contains("exists (");
|
||||
assertThat(sql).contains("exists (select 1 from");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotExists() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Order> subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query();
|
||||
Query<Customer> query = Ebean.find(Customer.class).alias("qt").where().notExists(subQuery).query();
|
||||
Query<Order> subQuery = DB.find(Order.class).alias("sq").where().raw("sq.kcustomer_id = qt.id").query();
|
||||
Query<Customer> query = DB.find(Customer.class).alias("qt").where().notExists(subQuery).query();
|
||||
|
||||
query.findList();
|
||||
String sql = query.getGeneratedSql();
|
||||
|
||||
assertThat(sql).contains("not exists (");
|
||||
assertThat(sql).contains("not exists (select 1 from");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,8 @@ import io.ebean.Query;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.CKeyParent;
|
||||
import org.tests.model.basic.Order;
|
||||
import org.tests.model.basic.OrderDetail;
|
||||
import org.tests.model.basic.OrderShipment;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
import org.tests.model.basic.Vehicle;
|
||||
import org.tests.model.basic.VehicleDriver;
|
||||
@@ -57,6 +59,75 @@ public class TestSubQuery extends BaseTestCase {
|
||||
assertThat(DB.find(Order.class).where().isIn("id", sq).findList()).hasSize(expectedSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase, that discovered, that DefaultOrmQuery.setDefaultSelectClause is set on subQueries with fetch path.
|
||||
* Also checks, that SqlTreeBuilder does not read id on Many2One props.
|
||||
*/
|
||||
@Test
|
||||
public void test_IsInWithFetchSubQuery1() {
|
||||
|
||||
List<Integer> productIds = new ArrayList<>();
|
||||
productIds.add(3);
|
||||
|
||||
Query<OrderDetail> sq = DB.createQuery(OrderDetail.class).fetch("order", "id").where()
|
||||
.isIn("product.id", productIds).query();
|
||||
|
||||
// execute the subQuery as copy (generatedSQL must be part of original query)
|
||||
Query<OrderDetail> debugSq = sq.copy();
|
||||
debugSq.findSingleAttribute();
|
||||
assertThat(debugSq.getGeneratedSql()).isEqualTo(
|
||||
"select t1.id from o_order_detail t0 join o_order t1 on t1.id = t0.order_id where t0.product_id in (?)");
|
||||
|
||||
Query<Order> query = DB.find(Order.class).select("shipDate").where().isIn("id", sq).query();
|
||||
query.findSingleAttribute();
|
||||
|
||||
assertThat(query.getGeneratedSql())
|
||||
.isEqualTo("select t0.ship_date from o_order t0 where (t0.id) in (" + debugSq.getGeneratedSql() + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test checks, that DefaultOrmQuery.markQueryJoins handles subQuery correct.
|
||||
*/
|
||||
@Test
|
||||
public void test_IsInWithFetchSubQuery2() {
|
||||
|
||||
Query<OrderDetail> sq = DB.createQuery(OrderDetail.class).fetch("order.customer", "anniversary").where()
|
||||
.eq("order.customer.name", "Roland")
|
||||
.query().setDistinct(true);
|
||||
|
||||
// execute the subQuery as copy (generatedSQL must be part of original query)
|
||||
Query<OrderDetail> debugSq = sq.copy();
|
||||
debugSq.findSingleAttribute();
|
||||
|
||||
Query<Order> query = DB.find(Order.class).select("status").where().isIn("shipDate", sq).query();
|
||||
query.findSingleAttribute();
|
||||
assertThat(query.getGeneratedSql())
|
||||
.isEqualTo("select t0.status from o_order t0 where (t0.ship_date) in (" + debugSq.getGeneratedSql() + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, that SqlTreeBuilder does not read id on One2Many props.
|
||||
*/
|
||||
@Test
|
||||
public void test_IsInWithFetchSubQuery3() {
|
||||
|
||||
List<Integer> productIds = new ArrayList<>();
|
||||
productIds.add(3);
|
||||
|
||||
Query<OrderDetail> sq = DB.createQuery(OrderDetail.class).fetch("order.shipments", "id").where()
|
||||
.isIn("product.id", productIds).query();
|
||||
|
||||
// execute the subQuery as copy (generatedSQL must be part of original query)
|
||||
Query<OrderDetail> debugSq = sq.copy();
|
||||
debugSq.findSingleAttribute();
|
||||
|
||||
Query<OrderShipment> query = DB.find(OrderShipment.class).select("shipTime").where().isIn("id", sq).query();
|
||||
query.findSingleAttribute();
|
||||
|
||||
assertThat(query.getGeneratedSql())
|
||||
.isEqualTo("select t0.ship_time from or_order_ship t0 where (t0.id) in (" + debugSq.getGeneratedSql() + ")");
|
||||
}
|
||||
|
||||
public void testCompositeKey() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ public class SqlQueryCancelTest extends BaseTestCase {
|
||||
doCancelOrmAtBegin(Query::findOne);
|
||||
doCancelOrmAtBegin(q -> q.setMaxRows(1000).findPagedList().getList()); // untested
|
||||
doCancelOrmAtBegin(Query::findSet);
|
||||
doCancelOrmAtBegin(Query::findSingleAttribute);
|
||||
doCancelOrmAtBegin(Query::findSingleAttributeList);
|
||||
doCancelOrmAtBegin(q -> q.select("name").findSingleAttribute());
|
||||
doCancelOrmAtBegin(q -> q.select("name").findSingleAttributeList());
|
||||
doCancelOrmAtBegin(Query::findStream);
|
||||
// testDuringRun(Query::findVersions);
|
||||
// EBasic has no history support, but it should work if @History is added
|
||||
@@ -138,8 +138,8 @@ public class SqlQueryCancelTest extends BaseTestCase {
|
||||
// findOne cannot be tested, as H2 does the cancel check every 128 rows only
|
||||
doCancelOrmDuringRun(q -> q.setMaxRows(1000).findPagedList().getList()); // untested
|
||||
doCancelOrmDuringRun(Query::findSet);
|
||||
doCancelOrmDuringRun(Query::findSingleAttribute);
|
||||
doCancelOrmDuringRun(Query::findSingleAttributeList);
|
||||
doCancelOrmDuringRun(q -> q.select("name").findSingleAttribute());
|
||||
doCancelOrmDuringRun(q -> q.select("name").findSingleAttributeList());
|
||||
doCancelOrmDuringRun(Query::findStream);
|
||||
// testDuringRun(Query::findVersions);
|
||||
// EBasic has no history support, but it should work if @History is added
|
||||
|
||||
@@ -176,7 +176,7 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
// change default collect query plan threshold to 200 micros
|
||||
QueryPlanInit init0 = new QueryPlanInit();
|
||||
init0.setAll(true);
|
||||
init0.setThresholdMicros(2);
|
||||
init0.thresholdMicros(2);
|
||||
final List<MetaQueryPlan> plans = server().getMetaInfoManager().queryPlanInit(init0);
|
||||
assertThat(plans.size()).isGreaterThan(1);
|
||||
|
||||
@@ -186,7 +186,7 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
// change query plan threshold to 100 micros
|
||||
QueryPlanInit init = new QueryPlanInit();
|
||||
init.setAll(true);
|
||||
init.setThresholdMicros(1);
|
||||
init.thresholdMicros(1);
|
||||
final List<MetaQueryPlan> appliedToPlans = server().getMetaInfoManager().queryPlanInit(init);
|
||||
assertThat(appliedToPlans.size()).isGreaterThan(4);
|
||||
|
||||
@@ -195,30 +195,30 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
|
||||
ServerMetrics metrics = DB.getDefault().getMetaInfoManager().collectMetrics();
|
||||
|
||||
List<MetaQueryMetric> planStats = metrics.getQueryMetrics();
|
||||
List<MetaQueryMetric> planStats = metrics.queryMetrics();
|
||||
assertThat(planStats.size()).isGreaterThan(4);
|
||||
|
||||
for (MetaQueryMetric planStat : planStats) {
|
||||
System.out.println(planStat);
|
||||
}
|
||||
|
||||
for (MetaTimedMetric txnTimed : metrics.getTimedMetrics()) {
|
||||
for (MetaTimedMetric txnTimed : metrics.timedMetrics()) {
|
||||
System.out.println(txnTimed);
|
||||
}
|
||||
|
||||
// obtains db query plans ...
|
||||
QueryPlanRequest request = new QueryPlanRequest();
|
||||
// collect max 1000 plans (use something more like 10)
|
||||
request.setMaxCount(1_000);
|
||||
request.maxCount(1_000);
|
||||
// don't collect any more plans if used 10 secs
|
||||
request.setMaxTimeMillis(10_000);
|
||||
request.maxTimeMillis(10_000);
|
||||
List<MetaQueryPlan> plans0 = server().getMetaInfoManager().queryPlanCollectNow(request);
|
||||
assertThat(plans0).isNotEmpty();
|
||||
|
||||
for (MetaQueryPlan plan : plans) {
|
||||
logger.info("queryplan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}",
|
||||
plan.getLabel(), plan.getQueryTimeMicros(), plan.getProfileLocation(),
|
||||
plan.getSql(), plan.getBind(), plan.getPlan());
|
||||
logger.info("queryPlan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}",
|
||||
plan.label(), plan.queryTimeMicros(), plan.profileLocation(),
|
||||
plan.sql(), plan.bind(), plan.plan());
|
||||
System.out.println(plan);
|
||||
}
|
||||
|
||||
@@ -242,9 +242,9 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
|
||||
assertThat(metricsJson).contains("\"name\":\"txn.main\"");
|
||||
assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\"");
|
||||
assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:44)\"");
|
||||
assertThat(metricsJson).contains("\"loc\":\"org.tests.model.basic.finder.CustomerFinder.byNameStatus\"");
|
||||
if (isH2() || isPostgres()) {
|
||||
assertThat(metricsJson).contains("\"hash\":\"cc20eb930403cfd418db2d0475c6e26a\"");
|
||||
assertThat(metricsJson).contains("\"hash\":\"de3affa5b4bff07e19c1c012590dcde6\"");
|
||||
assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,");
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class TestCustomerFinder extends BaseTestCase {
|
||||
assertThat(metricsJson).contains("\"name\":\"txn.main\"");
|
||||
assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\"");
|
||||
assertThat(metricsJson).doesNotContain("\"loc\":");
|
||||
assertThat(metricsJson).doesNotContain("\"hash\":");
|
||||
assertThat(metricsJson).doesNotContain("\"sqlHash\":");
|
||||
assertThat(metricsJson).doesNotContain("\"sql\":");
|
||||
}
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ public class SqlQueryTests extends BaseTestCase {
|
||||
|
||||
List<MetaTimedMetric> sqlMetrics = sqlMetrics();
|
||||
assertThat(sqlMetrics).hasSize(1);
|
||||
assertThat(sqlMetrics.get(0).getName()).isEqualTo("sql.query.findEach-Max10Rows");
|
||||
assertThat(sqlMetrics.get(0).name()).isEqualTo("sql.query.findEach-Max10Rows");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package org.tests.rawsql.nativesql;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Query;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.embedded.EAddress;
|
||||
import org.tests.model.embedded.EPerson;
|
||||
import org.tests.model.json.PlainBean;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -17,25 +20,31 @@ public class TestNativeWithEmbedded extends BaseTestCase {
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Map<String, Object> rawMap = new LinkedHashMap<>();
|
||||
rawMap.put("a","1");
|
||||
EPerson person = new EPerson();
|
||||
person.setName("Frank");
|
||||
EAddress address = new EAddress();
|
||||
address.setStreet("1 foo st");
|
||||
address.setCity("barv");
|
||||
address.setJbean(new PlainBean("hi", 3));
|
||||
address.setJraw(rawMap);
|
||||
person.setAddress(address);
|
||||
|
||||
Ebean.save(person);
|
||||
DB.save(person);
|
||||
|
||||
String sql = "select id, name, street, suburb, addr_city, addr_status from eperson where id = ?";
|
||||
String sql = "select id, name, street, suburb, addr_city, addr_status, addr_jbean, jraw from eperson where id = ?";
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
Query<EPerson> query = Ebean.findNative(EPerson.class, sql);
|
||||
Query<EPerson> query = DB.findNative(EPerson.class, sql);
|
||||
query.setParameter(person.getId());
|
||||
EPerson one = query.findOne();
|
||||
|
||||
assertThat(one.getName()).isEqualTo("Frank");
|
||||
assertThat(one.getAddress().getStreet()).isEqualTo("1 foo st");
|
||||
assertThat(one.getAddress().getJbean().getName()).isEqualTo("hi");
|
||||
assertThat(one.getAddress().getJraw().get("a")).isEqualTo("1");
|
||||
|
||||
List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
assertThat(loggedSql).hasSize(1);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TestNestedMandatory extends BaseTestCase {
|
||||
}
|
||||
|
||||
assertThat(txnMetrics).hasSize(2);
|
||||
assertThat(txnMetrics.get(1).getName()).isEqualTo("txn.named.outer");
|
||||
assertThat(txnMetrics.get(1).name()).isEqualTo("txn.named.outer");
|
||||
}
|
||||
|
||||
class Outer {
|
||||
|
||||
@@ -20,9 +20,9 @@ public class TestTransactionalReadOnly extends BaseTestCase {
|
||||
resetAllMetrics();
|
||||
executeTransactionalUsingReadOnlyDataSource();
|
||||
|
||||
final List<MetaTimedMetric> timedMetrics = collectMetrics().getTimedMetrics();
|
||||
final List<MetaTimedMetric> timedMetrics = collectMetrics().timedMetrics();
|
||||
final Optional<MetaTimedMetric> txnReadOnly = metric(timedMetrics, "txn.readonly");
|
||||
assertThat(txnReadOnly.get().getCount()).isEqualTo(1);
|
||||
assertThat(txnReadOnly.get().count()).isEqualTo(1);
|
||||
assertThat(metric(timedMetrics, "txn")).isEmpty();
|
||||
}
|
||||
|
||||
@@ -32,15 +32,15 @@ public class TestTransactionalReadOnly extends BaseTestCase {
|
||||
resetAllMetrics();
|
||||
executeTransactionalUsingMainDataSource();
|
||||
|
||||
final List<MetaTimedMetric> timedMetrics = collectMetrics().getTimedMetrics();
|
||||
final List<MetaTimedMetric> timedMetrics = collectMetrics().timedMetrics();
|
||||
final Optional<MetaTimedMetric> txnMain = metric(timedMetrics, "txn.main");
|
||||
assertThat(txnMain.get().getCount()).isEqualTo(1);
|
||||
assertThat(txnMain.get().count()).isEqualTo(1);
|
||||
assertThat(metric(timedMetrics, "txn.readonly")).isEmpty();
|
||||
}
|
||||
|
||||
private Optional<MetaTimedMetric> metric(List<MetaTimedMetric> timedMetrics, String name) {
|
||||
return timedMetrics.stream()
|
||||
.filter(metaTimedMetric -> metaTimedMetric.getName().equals(name))
|
||||
.filter(metaTimedMetric -> metaTimedMetric.name().equals(name))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
|
||||
@@ -126,8 +126,8 @@ public class TestSqlUpdateInTxn extends BaseTestCase {
|
||||
|
||||
List<MetaTimedMetric> sqlMetrics = sqlMetrics();
|
||||
assertThat(sqlMetrics).hasSize(1);
|
||||
assertThat(sqlMetrics.get(0).getName()).isEqualTo("sql.update.auditLargeUpdate");
|
||||
assertThat(sqlMetrics.get(0).getCount()).isEqualTo(1);
|
||||
assertThat(sqlMetrics.get(0).name()).isEqualTo("sql.update.auditLargeUpdate");
|
||||
assertThat(sqlMetrics.get(0).count()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user