mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b57c3302 | ||
|
|
f65ea96b89 | ||
|
|
a1bd0b469a | ||
|
|
fd5563e3da | ||
|
|
f9156ede55 | ||
|
|
10d2d591db | ||
|
|
998d8ed6f2 | ||
|
|
a8da472872 | ||
|
|
a9cdf9736a | ||
|
|
c930a1dd6b | ||
|
|
67ce6ef58e | ||
|
|
c4f28efc45 | ||
|
|
afa4bc06d9 | ||
|
|
828c9ce128 | ||
|
|
6f37a0bd72 | ||
|
|
036086af02 | ||
|
|
f34b5e52e0 |
+13
-4
@@ -1,7 +1,11 @@
|
||||
sudo: required
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
|
||||
addons:
|
||||
postgresql: "9.4"
|
||||
|
||||
@@ -9,15 +13,20 @@ services:
|
||||
- postgresql
|
||||
|
||||
before_script:
|
||||
- psql -c 'create extension pgcrypto;' -U postgres
|
||||
- psql -c 'create extension hstore;' -U postgres
|
||||
- psql -c 'create extension postgis;' -U postgres
|
||||
- psql -c 'create database unit;' -U postgres
|
||||
- ./.travis/setup_database
|
||||
|
||||
env:
|
||||
- EBEAN_DB=h2
|
||||
- EBEAN_DB=pg
|
||||
|
||||
install: true
|
||||
|
||||
script:
|
||||
- mvn clean test
|
||||
|
||||
after_failure:
|
||||
- ./.travis/print_surefire_reports
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "\n=== SUREFIRE REPORTS ===\n"
|
||||
|
||||
for file in target/surefire-reports/*.txt
|
||||
do
|
||||
echo ${file}
|
||||
cat ${file}
|
||||
echo
|
||||
done
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "\n=== SETUP DATABASE ===\n"
|
||||
|
||||
#set -e
|
||||
#set -x
|
||||
|
||||
# Setup postgres' users and databases
|
||||
sudo -u postgres psql -c "CREATE USER unit WITH PASSWORD 'unit';"
|
||||
sudo -u postgres psql -c 'CREATE DATABASE unit WITH OWNER unit;'
|
||||
sudo -u postgres psql unit -c 'CREATE EXTENSION hstore;'
|
||||
sudo -u postgres psql unit -c 'CREATE EXTENSION pgcrypto;'
|
||||
#sudo -u postgres psql test2 -c 'CREATE EXTENSION postgis;'
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>org.avaje.ebeanorm</groupId>
|
||||
<artifactId>avaje-ebeanorm</artifactId>
|
||||
<version>6.16.2</version>
|
||||
<version>6.16.4</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>avaje-ebeanorm</name>
|
||||
@@ -219,7 +219,7 @@
|
||||
<plugin>
|
||||
<groupId>org.avaje.ebeanorm</groupId>
|
||||
<artifactId>avaje-ebeanorm-mavenenhancer</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<version>4.9.1</version>
|
||||
<executions>
|
||||
<!-- Not going to enhance Model bean -->
|
||||
<execution>
|
||||
|
||||
@@ -585,6 +585,9 @@ public final class RawSql implements Serializable {
|
||||
* <p>
|
||||
* For example modify all mappings with table alias "c" to have the path prefix "customer".
|
||||
* </p>
|
||||
* <p>
|
||||
* For the "Root type" you don't need to specify a tableAliasMapping.
|
||||
* </p>
|
||||
*/
|
||||
public void tableAliasMapping(String tableAlias, String path) {
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ public class RawSqlBuilder {
|
||||
* <p>
|
||||
* For example modify all mappings with table alias "c" to have the path prefix "customer".
|
||||
* </p>
|
||||
* <p>
|
||||
* For the "Root type" you don't need to specify a tableAliasMapping.
|
||||
* </p>
|
||||
*/
|
||||
public RawSqlBuilder tableAliasMapping(String tableAlias, String path) {
|
||||
columnMapping.tableAliasMapping(tableAlias, path);
|
||||
|
||||
@@ -343,28 +343,10 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the lazy load succeeded. If not then mark this bean as having
|
||||
* failed lazy loading due to the underlying row being deleted.
|
||||
* <p>
|
||||
* We mark the bean this way rather than immediately fail as we might be batch
|
||||
* lazy loading and this bean might not be used by the client code at all.
|
||||
* Instead we will fail as soon as the client code tries to use this bean.
|
||||
* </p>
|
||||
* @param lazyLoadPropertyIndex the property that is expected to be loaded
|
||||
* Set lazy load failure flag.
|
||||
*/
|
||||
public boolean isLazyLoadFailure(int lazyLoadPropertyIndex) {
|
||||
if (lazyLoadProperty != -1 || !isLoadedProperty(lazyLoadPropertyIndex)) {
|
||||
lazyLoadFailure = true;
|
||||
return true;
|
||||
}
|
||||
lazyLoadFailure = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Id of the owner bean.
|
||||
*/
|
||||
public void setOwnerId(Object ownerId) {
|
||||
public void setLazyLoadFailure(Object ownerId) {
|
||||
this.lazyLoadFailure = true;
|
||||
this.ownerId = ownerId;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@ public class DbMigrationConfig {
|
||||
|
||||
protected String modelSuffix = ".model.xml";
|
||||
|
||||
protected boolean includeGeneratedFileComment;
|
||||
|
||||
/**
|
||||
* Return the DB platform to generate migration DDL for.
|
||||
*
|
||||
@@ -236,6 +238,20 @@ public class DbMigrationConfig {
|
||||
this.rollbackSuffix = rollbackSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the generated file comment should be included.
|
||||
*/
|
||||
public boolean isIncludeGeneratedFileComment() {
|
||||
return includeGeneratedFileComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if the generated file comment should be included.
|
||||
*/
|
||||
public void setIncludeGeneratedFileComment(boolean includeGeneratedFileComment) {
|
||||
this.includeGeneratedFileComment = includeGeneratedFileComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the migration version.
|
||||
* <p>
|
||||
@@ -281,6 +297,7 @@ public class DbMigrationConfig {
|
||||
dropSuffix = properties.get("migration.dropSuffix", dropSuffix);
|
||||
rollbackSuffix = properties.get("migration.rollbackSuffix", rollbackSuffix);
|
||||
modelSuffix = properties.get("migration.modelSuffix", modelSuffix);
|
||||
includeGeneratedFileComment = properties.getBoolean("migration.includeGeneratedFileComment", includeGeneratedFileComment);
|
||||
|
||||
platform = properties.getEnum(DbPlatformName.class, "migration.platform", platform);
|
||||
suppressRollback = properties.getBoolean("migration.suppressRollback", suppressRollback);
|
||||
|
||||
@@ -59,6 +59,8 @@ public class DbMigration {
|
||||
|
||||
private static final String initialVersion = "1.0";
|
||||
|
||||
private static final String GENERATED_COMMENT = "THIS IS A GENERATED FILE - DO NOT MODIFY";
|
||||
|
||||
/**
|
||||
* Set to true if DbMigration run with online EbeanServer instance.
|
||||
*/
|
||||
@@ -304,7 +306,8 @@ public class DbMigration {
|
||||
if (file.exists()) {
|
||||
return false;
|
||||
}
|
||||
MigrationXmlWriter xmlWriter = new MigrationXmlWriter();
|
||||
String comment = migrationConfig.isIncludeGeneratedFileComment() ? GENERATED_COMMENT : null;
|
||||
MigrationXmlWriter xmlWriter = new MigrationXmlWriter(comment);
|
||||
xmlWriter.write(dbMigration, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
+29
-2
@@ -191,6 +191,25 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
.endOfStatement().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or replace the with_history view with explicit columns.
|
||||
*/
|
||||
protected void createWithHistoryView(DdlBuffer apply, String baseTableName, List<String> columns) throws IOException {
|
||||
|
||||
apply.append("create or replace view ").append(baseTableName).append(viewSuffix).append(" as select ");
|
||||
appendColumnNames(apply, columns, "");
|
||||
appendSysPeriodColumns(apply, ", ");
|
||||
apply.append(" from ").append(baseTableName).append(" union all select ");
|
||||
appendColumnNames(apply, columns, "");
|
||||
appendSysPeriodColumns(apply, ", ");
|
||||
apply.append(" from ").append(baseTableName).append(historySuffix).endOfStatement().end();
|
||||
}
|
||||
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
appendColumnName(apply, prefix, sysPeriodStart);
|
||||
appendColumnName(apply, prefix, sysPeriodEnd);
|
||||
}
|
||||
|
||||
protected void dropHistoryTableEtc(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
|
||||
buffer.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
@@ -203,8 +222,6 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
buffer.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriodEnd).endOfStatement();
|
||||
}
|
||||
|
||||
//protected abstract void addFunction(DdlBuffer apply, String procedureName, String historyTable, List<String> includedColumns) throws IOException;
|
||||
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
|
||||
@@ -225,6 +242,16 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single column to the buffer if it is not null.
|
||||
*/
|
||||
protected void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
|
||||
|
||||
if (columnName != null) {
|
||||
buffer.append(prefix).append(columnName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of included columns in order.
|
||||
*/
|
||||
|
||||
+19
-1
@@ -45,6 +45,11 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
appendColumnName(apply, prefix, sysPeriod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
buffer.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriod).endOfStatement();
|
||||
@@ -115,11 +120,12 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
if (update != null) {
|
||||
apply.append("-- Regenerated ").append(procedureName).newLine();
|
||||
apply.append("-- changes: ").append(update.description()).newLine();
|
||||
|
||||
recreateHistoryView(apply, table.getName(), includedColumns);
|
||||
}
|
||||
|
||||
addFunction(apply, procedureName, historyTable, includedColumns);
|
||||
|
||||
|
||||
if (update != null) {
|
||||
// put a reverted version into the rollback buffer
|
||||
update.toRevertedColumns(includedColumns);
|
||||
@@ -128,10 +134,22 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
rollback.append("-- Revert regenerated ").append(procedureName).newLine();
|
||||
rollback.append("-- revert changes: ").append(update.description()).newLine();
|
||||
|
||||
recreateHistoryView(rollback, table.getName(), includedColumns);
|
||||
addFunction(rollback, procedureName, historyTable, includedColumns);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For postgres we need to drop and recreate the view. Well, we could add columns to the end of the view
|
||||
* but otherwise we need to drop and create it.
|
||||
*/
|
||||
private void recreateHistoryView(DdlBuffer buffer, String baseTableName, List<String> includedColumns) throws IOException {
|
||||
|
||||
buffer.append("drop view if exists ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
|
||||
createWithHistoryView(buffer, baseTableName, includedColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
* <attGroup ref="{http://ebean-orm.github.io/xml/ns/dbmigration}tablespaceAttributes"/>
|
||||
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="withHistory" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="draft" type="{http://www.w3.org/2001/XMLSchema}boolean" />
|
||||
* <attribute name="identityType" type="{http://ebean-orm.github.io/xml/ns/dbmigration}identityType" />
|
||||
* <attribute name="sequenceName" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="sequenceInitial" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
|
||||
@@ -59,6 +60,8 @@ public class CreateTable {
|
||||
protected String name;
|
||||
@XmlAttribute(name = "withHistory")
|
||||
protected Boolean withHistory;
|
||||
@XmlAttribute(name = "draft")
|
||||
protected Boolean draft;
|
||||
@XmlAttribute(name = "identityType")
|
||||
protected IdentityType identityType;
|
||||
@XmlAttribute(name = "sequenceName")
|
||||
@@ -213,6 +216,30 @@ public class CreateTable {
|
||||
this.withHistory = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the draft property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isDraft() {
|
||||
return draft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the draft property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setDraft(Boolean value) {
|
||||
this.draft = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the identityType property.
|
||||
*
|
||||
|
||||
@@ -7,22 +7,46 @@ import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Simple writer for output of the Migration/ChangeSet as an XML document.
|
||||
*/
|
||||
public class MigrationXmlWriter {
|
||||
|
||||
private final String comment;
|
||||
|
||||
public MigrationXmlWriter(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a Migration to a file as an xml document to the file.
|
||||
*/
|
||||
public void write(Migration migration, File file) {
|
||||
|
||||
try {
|
||||
|
||||
FileWriter writer = new FileWriter(file);
|
||||
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
|
||||
if (comment != null) {
|
||||
writer.write("<!-- ");
|
||||
writer.write(comment);
|
||||
writer.write(" -->\n");
|
||||
}
|
||||
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Migration.class);
|
||||
Marshaller marshaller = jaxbContext.createMarshaller();
|
||||
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
marshaller.marshal(migration, file);
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
|
||||
|
||||
marshaller.marshal(migration, writer);
|
||||
|
||||
writer.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@@ -10,13 +10,14 @@ import com.avaje.ebean.dbmigration.migration.DropHistoryTable;
|
||||
import com.avaje.ebean.dbmigration.migration.DropTable;
|
||||
import com.avaje.ebean.dbmigration.migration.IdentityType;
|
||||
import com.avaje.ebean.dbmigration.migration.UniqueConstraint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -38,6 +39,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class MTable {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MTable.class);
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
@@ -150,6 +153,7 @@ public class MTable {
|
||||
this.tablespace = createTable.getTablespace();
|
||||
this.indexTablespace = createTable.getIndexTablespace();
|
||||
this.withHistory = Boolean.TRUE.equals(createTable.isWithHistory());
|
||||
this.draft = Boolean.TRUE.equals(createTable.isDraft());
|
||||
this.sequenceName = createTable.getSequenceName();
|
||||
this.sequenceInitial = toInt(createTable.getSequenceInitial());
|
||||
this.sequenceAllocate = toInt(createTable.getSequenceAllocate());
|
||||
@@ -194,6 +198,9 @@ public class MTable {
|
||||
if (withHistory) {
|
||||
createTable.setWithHistory(Boolean.TRUE);
|
||||
}
|
||||
if (draft) {
|
||||
createTable.setDraft(Boolean.TRUE);
|
||||
}
|
||||
|
||||
for (MColumn column : this.columns.values()) {
|
||||
// filter out draftOnly columns from the base table
|
||||
@@ -244,24 +251,29 @@ public class MTable {
|
||||
|
||||
addColumn = null;
|
||||
|
||||
Set<String> mappedColumns = new LinkedHashSet<String>();
|
||||
Map<String, MColumn> newColumnMap = newTable.getColumns();
|
||||
|
||||
Collection<MColumn> newColumns = newTable.getColumns().values();
|
||||
for (MColumn newColumn : newColumns) {
|
||||
MColumn localColumn = columns.get(newColumn.getName());
|
||||
// compare newColumns to existing columns (look for new and diff columns)
|
||||
for (MColumn newColumn : newColumnMap.values()) {
|
||||
MColumn localColumn = this.columns.get(newColumn.getName());
|
||||
if (localColumn == null) {
|
||||
diffNewColumn(newColumn);
|
||||
// can ignore if draftOnly column and non-draft table
|
||||
if (!newColumn.isDraftOnly() || draft) {
|
||||
diffNewColumn(newColumn);
|
||||
}
|
||||
} else {
|
||||
// note that if there are alter column changes in here then
|
||||
// the table withHistory is taken into account
|
||||
localColumn.compare(modelDiff, this, newColumn);
|
||||
mappedColumns.add(newColumn.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Collection<MColumn> existingColumns = columns.values();
|
||||
for (MColumn existingColumn : existingColumns) {
|
||||
if (!mappedColumns.contains(existingColumn.getName())) {
|
||||
// compare existing columns (look for dropped columns)
|
||||
for (MColumn existingColumn : columns.values()) {
|
||||
MColumn newColumn = newColumnMap.get(existingColumn.getName());
|
||||
if (newColumn == null) {
|
||||
diffDropColumn(modelDiff, existingColumn);
|
||||
} else if (newColumn.isDraftOnly() && !draft) {
|
||||
// effectively a drop column (draft only column on a non-draft table)
|
||||
logger.trace("... drop column {} from table {} as now draftOnly", newColumn.getName(), name);
|
||||
diffDropColumn(modelDiff, existingColumn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Request for loading ManyToOne and OneToOne relationships.
|
||||
@@ -21,8 +23,6 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
|
||||
private final LoadBeanBuffer loadBuffer;
|
||||
|
||||
private final int lazyLoadPropertyIndex;
|
||||
|
||||
private final String lazyLoadProperty;
|
||||
|
||||
private final boolean loadCache;
|
||||
@@ -30,24 +30,23 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
/**
|
||||
* Construct for lazy load request.
|
||||
*/
|
||||
public LoadBeanRequest(LoadBeanBuffer LoadBuffer, int lazyLoadPropertyIndex, String lazyLoadProperty, boolean loadCache) {
|
||||
this(LoadBuffer, null, true, lazyLoadPropertyIndex, lazyLoadProperty, loadCache);
|
||||
public LoadBeanRequest(LoadBeanBuffer LoadBuffer, String lazyLoadProperty, boolean loadCache) {
|
||||
this(LoadBuffer, null, true, lazyLoadProperty, loadCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for secondary query.
|
||||
*/
|
||||
public LoadBeanRequest(LoadBeanBuffer LoadBuffer, OrmQueryRequest<?> parentRequest) {
|
||||
this(LoadBuffer, parentRequest, false, -1, null, false);
|
||||
this(LoadBuffer, parentRequest, false, null, false);
|
||||
}
|
||||
|
||||
private LoadBeanRequest(LoadBeanBuffer loadBuffer, OrmQueryRequest<?> parentRequest, boolean lazy,
|
||||
int lazyLoadPropertyIndex, String lazyLoadProperty, boolean loadCache) {
|
||||
String lazyLoadProperty, boolean loadCache) {
|
||||
|
||||
super(parentRequest, lazy);
|
||||
this.loadBuffer = loadBuffer;
|
||||
this.batch = loadBuffer.getBatch();
|
||||
this.lazyLoadPropertyIndex = lazyLoadPropertyIndex;
|
||||
this.lazyLoadProperty = lazyLoadProperty;
|
||||
this.loadCache = loadCache;
|
||||
}
|
||||
@@ -96,7 +95,7 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
*/
|
||||
public List<Object> getIdList(int batchSize) {
|
||||
|
||||
ArrayList<Object> idList = new ArrayList<Object>(batchSize);
|
||||
List<Object> idList = new ArrayList<Object>(batchSize);
|
||||
|
||||
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
|
||||
for (int i = 0; i < batch.size(); i++) {
|
||||
@@ -124,7 +123,7 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
/**
|
||||
* Configure the query for lazy loading execution.
|
||||
*/
|
||||
public void configureQuery(SpiQuery<?> query) {
|
||||
public void configureQuery(SpiQuery<?> query, List<Object> idList) {
|
||||
|
||||
query.setMode(SpiQuery.Mode.LAZYLOAD_BEAN);
|
||||
query.setPersistenceContext(loadBuffer.getPersistenceContext());
|
||||
@@ -137,7 +136,13 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
query.setLazyLoadBatchSize(getBatchSize());
|
||||
}
|
||||
|
||||
loadBuffer.configureQuery(query, getLazyLoadProperty());
|
||||
loadBuffer.configureQuery(query, lazyLoadProperty);
|
||||
|
||||
if (idList.size() == 1) {
|
||||
query.where().idEq(idList.get(0));
|
||||
} else {
|
||||
query.where().idIn(idList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,25 +150,27 @@ public class LoadBeanRequest extends LoadRequest {
|
||||
*/
|
||||
public void postLoad(List<?> list) {
|
||||
|
||||
if (isLoadCache()) {
|
||||
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
desc.cacheBeanPutData((EntityBean) list.get(i));
|
||||
Set<Object> loadedIds = new HashSet<Object>();
|
||||
|
||||
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
|
||||
// collect Ids and maybe load bean cache
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
EntityBean loadedBean = (EntityBean) list.get(i);
|
||||
loadedIds.add(desc.getId(loadedBean));
|
||||
if (isLoadCache()) {
|
||||
desc.cacheBeanPutData(loadedBean);
|
||||
}
|
||||
}
|
||||
|
||||
if (lazyLoadPropertyIndex > -1) {
|
||||
// this is a lazy loading query so check for lazy loading failure (due to deleted rows)
|
||||
if (lazyLoadProperty != null) {
|
||||
for (int i = 0; i < batch.size(); i++) {
|
||||
// check if the underlying row in DB was deleted. Mark the bean as 'failed' if
|
||||
// necessary but allow processing to continue until it is accessed by client code
|
||||
EntityBeanIntercept ebi = batch.get(i);
|
||||
// all beans in the batch should have this property loaded now
|
||||
if (ebi.isLazyLoadFailure(lazyLoadPropertyIndex)) {
|
||||
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
|
||||
Object beanId = desc.getId(ebi.getOwner());
|
||||
ebi.setOwnerId(beanId);
|
||||
logger.info("Lazy loading unsuccessful for type:" + desc.getName() + " id:" + beanId + " - expecting when bean has been deleted");
|
||||
Object id = desc.getId(ebi.getOwner());
|
||||
if (!loadedIds.contains(id)) {
|
||||
logger.info("Lazy loading unsuccessful for type:" + desc.getName() + " id:" + id + " - expecting when bean has been deleted");
|
||||
ebi.setLazyLoadFailure(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,16 +206,9 @@ public class DefaultBeanLoader {
|
||||
}
|
||||
|
||||
SpiQuery<?> query = (SpiQuery<?>) server.createQuery(loadRequest.getBeanType());
|
||||
loadRequest.configureQuery(query);
|
||||
|
||||
if (idList.size() == 1) {
|
||||
query.where().idEq(idList.get(0));
|
||||
} else {
|
||||
query.where().idIn(idList);
|
||||
}
|
||||
loadRequest.configureQuery(query, idList);
|
||||
|
||||
List<?> list = executeQuery(loadRequest, query);
|
||||
|
||||
loadRequest.postLoad(list);
|
||||
|
||||
// log the query (for testing secondary queries)
|
||||
|
||||
@@ -190,7 +190,7 @@ public class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContex
|
||||
}
|
||||
}
|
||||
|
||||
LoadBeanRequest req = new LoadBeanRequest(this, ebi.getLazyLoadPropertyIndex(), ebi.getLazyLoadProperty(), context.hitCache);
|
||||
LoadBeanRequest req = new LoadBeanRequest(this, ebi.getLazyLoadProperty(), context.hitCache);
|
||||
context.desc.getEbeanServer().loadBean(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="withHistory" type="xsd:boolean"/>
|
||||
<xsd:attribute name="draft" type="xsd:boolean"/>
|
||||
<xsd:attribute name="identityType" type="identityType"/>
|
||||
<xsd:attribute name="sequenceName" type="xsd:string"/>
|
||||
<xsd:attribute name="sequenceInitial" type="xsd:positiveInteger"/>
|
||||
|
||||
+16
-2
@@ -5,16 +5,30 @@ import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class MigrationXmlWriterTest {
|
||||
|
||||
@Test
|
||||
public void testReadWrite() throws Exception {
|
||||
|
||||
Migration migration = MigrationXmlReader.read("/container/test-create-table.xml");
|
||||
assertThat(migration.getChangeSet()).hasSize(1);
|
||||
assertThat(migration.getChangeSet().get(0).getChangeSetChildren()).hasSize(3);
|
||||
|
||||
File temp = File.createTempFile("migrationWrite",".xml");
|
||||
MigrationXmlWriter writer = new MigrationXmlWriter();
|
||||
writer.write(migration, temp);
|
||||
new MigrationXmlWriter("THIS IS A GENERATED FILE - DO NOT MODIFY").write(migration, temp);
|
||||
|
||||
Migration migrationRead = MigrationXmlReader.read(temp);
|
||||
assertThat(migrationRead.getChangeSet()).hasSize(1);
|
||||
assertThat(migrationRead.getChangeSet().get(0).getChangeSetChildren()).hasSize(3);
|
||||
|
||||
temp = File.createTempFile("migrationWrite",".xml");
|
||||
new MigrationXmlWriter(null).write(migration, temp);
|
||||
|
||||
Migration migrationRead2 = MigrationXmlReader.read(temp);
|
||||
|
||||
assertThat(migrationRead2.getChangeSet()).hasSize(1);
|
||||
assertThat(migrationRead.getChangeSet().get(0).getChangeSetChildren()).hasSize(3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.avaje.tests.inheritance;
|
||||
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.tests.model.basic.Car;
|
||||
import com.avaje.tests.model.basic.Truck;
|
||||
import com.avaje.tests.model.basic.Vehicle;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class TestInheritanceBatchLazyLoad {
|
||||
|
||||
@Test
|
||||
public void lazyLoadProperty_when_propertyNotOnAllInheritanceTypes() {
|
||||
|
||||
Car c = new Car();
|
||||
c.setLicenseNumber("VZVZ1");
|
||||
c.setDriver("CarDriver");
|
||||
Ebean.save(c);
|
||||
|
||||
Truck t = new Truck();
|
||||
t.setLicenseNumber("VZVZ2");
|
||||
t.setCapacity(20D);
|
||||
Ebean.save(t);
|
||||
|
||||
|
||||
List<Vehicle> list = Ebean.find(Vehicle.class)
|
||||
.select("licenseNumber")
|
||||
.where().startsWith("licenseNumber","VZVZ")
|
||||
.order().asc("licenseNumber")
|
||||
.findList();
|
||||
|
||||
assertThat(list).hasSize(2);
|
||||
|
||||
Car car = (Car)list.get(0);
|
||||
car.getNotes();
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,14 @@ public class Car extends Vehicle {
|
||||
private String driver;
|
||||
|
||||
@ManyToOne
|
||||
TruckRef carRef;
|
||||
private TruckRef carRef;
|
||||
|
||||
@OneToMany(mappedBy = "car")
|
||||
@OrderBy("fuse.locationCode")
|
||||
private Set<CarAccessory> accessories = new HashSet<CarAccessory>();
|
||||
|
||||
private String notes;
|
||||
|
||||
public String getDriver() {
|
||||
return driver;
|
||||
}
|
||||
@@ -33,6 +35,14 @@ public class Car extends Vehicle {
|
||||
this.driver = driver;
|
||||
}
|
||||
|
||||
public String getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(String notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public TruckRef getCarRef() {
|
||||
return carRef;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.junit.Test;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.StrictAssertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -127,6 +128,50 @@ public class TestRawSqlMasterDetail extends BaseTestCase {
|
||||
assertFalse(ordersFromRaw.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableAlias_with_rootTypeMappedNotMapped() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
String rs = "select o.id, o.status " +
|
||||
"from o_order o order by o.id asc";
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.create();
|
||||
|
||||
List<Order> ordersFromRaw = Ebean.find(Order.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
for (Order order : ordersFromRaw) {
|
||||
assertThat(order.getId()).isNotNull();
|
||||
assertThat(order.getStatus()).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableAlias_with_rootTypeMappedToNullPath() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
String rs = "select o.id, o.status " +
|
||||
"from o_order o order by o.id asc";
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("o", null)
|
||||
.create();
|
||||
|
||||
List<Order> ordersFromRaw = Ebean.find(Order.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
for (Order order : ordersFromRaw) {
|
||||
assertThat(order.getId()).isNotNull();
|
||||
assertThat(order.getStatus()).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithMultipleManys() {
|
||||
|
||||
|
||||
@@ -110,8 +110,8 @@ datasource.ora.password=unit
|
||||
datasource.ora.databaseUrl=jdbc:oracle:thin:@//127.0.0.1:1521/orcl
|
||||
datasource.ora.databaseDriver=oracle.jdbc.driver.OracleDriver
|
||||
|
||||
datasource.pg.username=postgres
|
||||
datasource.pg.password=
|
||||
datasource.pg.username=unit
|
||||
datasource.pg.password=unit
|
||||
datasource.pg.databaseUrl=jdbc:postgresql://127.0.0.1:5432/unit
|
||||
datasource.pg.databaseDriver=org.postgresql.Driver
|
||||
|
||||
|
||||
Reference in New Issue
Block a user