mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-23 21:15:52 +00:00
Merge branch 'master' into feature/redundant-local-var
This commit is contained in:
@@ -77,6 +77,12 @@ public class ServerConfig {
|
||||
*/
|
||||
private String name = "db";
|
||||
|
||||
/**
|
||||
* When false (default) H2 automatically uses DDL generate and run
|
||||
* (i.e. assumes we are running tests using in memory h2).
|
||||
*/
|
||||
private boolean h2ProductionMode;
|
||||
|
||||
/**
|
||||
* Typically configuration type objects that are passed by this ServerConfig
|
||||
* to plugins. For example - IgniteConfiguration passed to Ignite plugin.
|
||||
@@ -509,6 +515,27 @@ public class ServerConfig {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if H2 should be used in production mode.
|
||||
* <p>
|
||||
* Otherwise it is assumed we are using H2 for testing and DDL generate and run is turned on.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isH2ProductionMode() {
|
||||
return h2ProductionMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true for H2 to be used in production mode.
|
||||
* <p>
|
||||
* Do this when we want to use H2 and not have the DDL generation and run automatically turned on.
|
||||
* Otherwise it is assumed we are using H2 for testing purposes.
|
||||
* </p>
|
||||
*/
|
||||
public void setH2ProductionMode(boolean h2ProductionMode) {
|
||||
this.h2ProductionMode = h2ProductionMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the container / clustering configuration.
|
||||
* <p/>
|
||||
@@ -1444,6 +1471,12 @@ public class ServerConfig {
|
||||
*/
|
||||
public void setDatabasePlatform(DatabasePlatform databasePlatform) {
|
||||
this.databasePlatform = databasePlatform;
|
||||
if (!h2ProductionMode && databasePlatform != null && databasePlatform.isPlatform(Platform.H2)) {
|
||||
// we are using H2 to run tests so turn on DDL generation and run
|
||||
this.ddlGenerate = true;
|
||||
this.ddlRun = true;
|
||||
this.ddlCreateOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2460,6 +2493,7 @@ public class ServerConfig {
|
||||
jsonDateTime = JsonConfig.DateTime.MILLIS;
|
||||
}
|
||||
|
||||
h2ProductionMode = p.getBoolean("h2ProductionMode", h2ProductionMode);
|
||||
ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
|
||||
ddlRun = p.getBoolean("ddl.run", ddlRun);
|
||||
ddlCreateOnly = p.getBoolean("ddl.createOnly", ddlCreateOnly);
|
||||
|
||||
@@ -240,7 +240,7 @@ public class DefaultContainer implements SpiContainer {
|
||||
DatabasePlatform db = factory.create(config);
|
||||
db.configure(config);
|
||||
config.setDatabasePlatform(db);
|
||||
logger.info("DatabasePlatform name:" + config.getName() + " platform:" + db.getName());
|
||||
logger.info("DatabasePlatform name:{} platform:{}", config.getName(), db.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -363,8 +363,15 @@ class CQueryBuilder {
|
||||
RawSql.ColumnMapping.Column column = it.next();
|
||||
String propertyName = column.getPropertyName();
|
||||
if (!RawSqlBuilder.IGNORE_COLUMN.equals(propertyName)) {
|
||||
|
||||
ElPropertyValue el = descriptor.getElGetValue(propertyName);
|
||||
if (el == null && propertyName.endsWith("Id")) {
|
||||
// try default naming convention for foreign key columns
|
||||
String foreignIdPath = assocOneIdPath(propertyName);
|
||||
el = descriptor.getElGetValue(foreignIdPath);
|
||||
if (el != null) {
|
||||
propertyName = foreignIdPath;
|
||||
}
|
||||
}
|
||||
if (el == null) {
|
||||
throw new PersistenceException("Property [" + propertyName + "] not found on " + descriptor.getFullName());
|
||||
} else {
|
||||
@@ -404,6 +411,13 @@ class CQueryBuilder {
|
||||
return new SqlTreeBuilder(request, predicates, detail, rawNoId).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a path for a foreign key property using the default naming convention.
|
||||
*/
|
||||
private String assocOneIdPath(String propertyName) {
|
||||
return propertyName.substring(0, propertyName.length() - 2) + ".id";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL response with row limiting (when not an update statement).
|
||||
*/
|
||||
|
||||
@@ -35,7 +35,13 @@ class CQueryPlanRawSql extends CQueryPlan {
|
||||
|
||||
// set the resultSet index positions for the property expressions
|
||||
for (int i = 0; i < chain.size(); i++) {
|
||||
indexPositions[i] = 1 + columnMapping.getIndexPosition(chain.get(i));
|
||||
String logicalPropertyPath = chain.get(i);
|
||||
int mappedPosition = columnMapping.getIndexPosition(logicalPropertyPath);
|
||||
if (mappedPosition == -1 && logicalPropertyPath.endsWith(".id")) {
|
||||
// try a automatically mapped foreign key
|
||||
mappedPosition = columnMapping.getIndexPosition(foreignKeyPath(logicalPropertyPath));
|
||||
}
|
||||
indexPositions[i] = 1 + mappedPosition;
|
||||
}
|
||||
|
||||
// check and handle the case where a discriminator column for
|
||||
@@ -51,4 +57,12 @@ class CQueryPlanRawSql extends CQueryPlan {
|
||||
|
||||
return indexPositions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path for a foreign key column that was automatically mapped.
|
||||
*/
|
||||
private String foreignKeyPath(String logicalPropertyPath) {
|
||||
// trim the .id and replace with Id ... to reverse the auto fk mapping earlier
|
||||
return logicalPropertyPath.substring(0, logicalPropertyPath.length() - 3) + "Id";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public class EbeanServerFactory_ServerConfigStart_Test {
|
||||
config.setName("h2");
|
||||
config.loadFromProperties();
|
||||
config.setName("h2other");
|
||||
config.setH2ProductionMode(true);
|
||||
config.setDdlGenerate(false);
|
||||
config.setDdlRun(false);
|
||||
config.setDefaultServer(false);
|
||||
|
||||
@@ -34,9 +34,11 @@ public class ServerConfigTest {
|
||||
props.setProperty("jdbcFetchSizeFindList", "43");
|
||||
props.setProperty("backgroundExecutorShutdownSecs", "98");
|
||||
props.setProperty("backgroundExecutorSchedulePoolSize", "4");
|
||||
props.setProperty("h2ProductionMode", "true");
|
||||
|
||||
serverConfig.loadFromProperties(props);
|
||||
|
||||
assertTrue(serverConfig.isH2ProductionMode());
|
||||
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatchOnCascade());
|
||||
assertEquals(ServerConfig.DbUuid.BINARY, serverConfig.getDbUuid());
|
||||
|
||||
@@ -31,6 +31,7 @@ public class ModelBuild_compoundKeyTest extends BaseTestCase {
|
||||
config.setName("h2");
|
||||
config.loadFromProperties();
|
||||
config.setName("h2other");
|
||||
config.setH2ProductionMode(true);
|
||||
config.setDdlGenerate(false);
|
||||
config.setDdlRun(false);
|
||||
config.setDefaultServer(false);
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ public class ModelBuild_explicitSequencesTest extends BaseTestCase {
|
||||
config.setName("h2");
|
||||
config.loadFromProperties();
|
||||
config.setName("h2other");
|
||||
config.setH2ProductionMode(true);
|
||||
config.setDdlGenerate(false);
|
||||
config.setDdlRun(false);
|
||||
config.setDefaultServer(false);
|
||||
|
||||
@@ -73,6 +73,7 @@ public class BeanPersistControllerTest {
|
||||
ServerConfig config = new ServerConfig();
|
||||
|
||||
config.setName("h2ebasicver");
|
||||
config.setH2ProductionMode(true);
|
||||
config.loadFromProperties();
|
||||
config.setDdlGenerate(true);
|
||||
config.setDdlRun(true);
|
||||
|
||||
@@ -52,6 +52,7 @@ public class BeanPostLoadTest extends BaseTestCase {
|
||||
|
||||
config.setName("h2ebasicver");
|
||||
config.loadFromProperties();
|
||||
config.setH2ProductionMode(true);
|
||||
config.setDdlGenerate(true);
|
||||
config.setDdlRun(true);
|
||||
|
||||
|
||||
@@ -47,11 +47,6 @@ public class Order implements Serializable {
|
||||
COMPLETE
|
||||
}
|
||||
|
||||
public Order() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
package com.avaje.tests.model.converstation;
|
||||
|
||||
import com.avaje.ebean.annotation.History;
|
||||
import com.avaje.ebean.annotation.HistoryExclude;
|
||||
import com.avaje.tests.model.BaseModel;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.annotation.History;
|
||||
import com.avaje.ebean.annotation.HistoryExclude;
|
||||
import com.avaje.ebean.annotation.WhenModified;
|
||||
import com.avaje.tests.model.BaseModel;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@History
|
||||
@Entity
|
||||
@Table(name="c_user")
|
||||
@Table(name = "c_user")
|
||||
public class User extends BaseModel {
|
||||
|
||||
boolean inactive;
|
||||
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
String email;
|
||||
|
||||
@HistoryExclude
|
||||
@@ -28,12 +25,9 @@ public class User extends BaseModel {
|
||||
@ManyToOne
|
||||
Group group;
|
||||
|
||||
@WhenModified
|
||||
Timestamp whenModified;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
|
||||
public boolean isInactive() {
|
||||
return inactive;
|
||||
}
|
||||
@@ -74,13 +68,4 @@ public class User extends BaseModel {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getWhenModified() {
|
||||
return whenModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWhenModified(Timestamp whenModified) {
|
||||
this.whenModified = whenModified;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.RawSql;
|
||||
import com.avaje.ebean.RawSqlBuilder;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.EBasic;
|
||||
import com.avaje.tests.model.basic.Order;
|
||||
import com.avaje.tests.model.basic.OrderDetail;
|
||||
@@ -13,7 +14,7 @@ import org.junit.Test;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.StrictAssertions.assertThat;
|
||||
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;
|
||||
@@ -54,6 +55,72 @@ public class TestRawSqlMasterDetail extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForeignKeyColumn() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
// billing_address_id fk column is automatically
|
||||
// mapped to the logical path: billingAddress.id
|
||||
|
||||
String rs = "select c.id, c.name, c.billing_address_id, c.updtime "+
|
||||
"from o_customer c " +
|
||||
"order by c.id";
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs).create();
|
||||
|
||||
List<Customer> customers = Ebean.find(Customer.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleNestedColumn() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
|
||||
String rs = "select c.id, c.name, c.billing_address_id, ba.line_1, ba.city, c.updtime "+
|
||||
"from o_customer c " +
|
||||
" left join o_address ba on ba.id = c.billing_address_id "+
|
||||
"order by c.id";
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("ba", "billingAddress")
|
||||
.create();
|
||||
|
||||
List<Customer> customers = Ebean.find(Customer.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleJoinColumn() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
String rs = "select c.id, c.name, c.billing_address_id, ba.line_1, ba.city, c.updtime, sa.id, sa.line_1, sa.city "+
|
||||
"from o_customer c " +
|
||||
" left join o_address ba on ba.id = c.billing_address_id "+
|
||||
" left join o_address sa on sa.id = c.shipping_address_id "+
|
||||
"order by c.id";
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("ba", "billingAddress")
|
||||
.tableAliasMapping("sa", "shippingAddress")
|
||||
.create();
|
||||
|
||||
List<Customer> customers = Ebean.find(Customer.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
assertThat(customers).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithTableAliasMapping() {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ public class TestAutoCommitDataSource extends BaseTestCase {
|
||||
|
||||
ServerConfig config = new ServerConfig();
|
||||
config.setName("h2autocommit");
|
||||
config.setH2ProductionMode(true);
|
||||
config.loadFromProperties();
|
||||
config.setDataSource(pool);
|
||||
config.setDefaultServer(false);
|
||||
|
||||
@@ -78,10 +78,10 @@
|
||||
<logger name="com.avaje.ebean" level="INFO"/>
|
||||
<logger name="org.avaje.ebean" level="INFO"/>
|
||||
|
||||
<!--<logger name="org.avaje.ebean.SQL" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.TXN" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.SUM" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.ELA" level="TRACE"/>-->
|
||||
<logger name="org.avaje.ebean.SQL" level="TRACE"/>
|
||||
<logger name="org.avaje.ebean.TXN" level="TRACE"/>
|
||||
<logger name="org.avaje.ebean.SUM" level="TRACE"/>
|
||||
<logger name="org.avaje.ebean.ELA" level="TRACE"/>
|
||||
|
||||
<!--<logger name="org.avaje.ebean.cache.QUERY" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.cache.BEAN" level="TRACE"/>-->
|
||||
|
||||
Reference in New Issue
Block a user