mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1508 - Invalid SQL used to fetch identity value for @Draftable with database platform that uses Identity but not getGeneratedKeys
This commit is contained in:
@@ -8,7 +8,9 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class DbIdentity {
|
||||
|
||||
private static final Pattern TABLE_REPLACE = Pattern.compile("{table}", Pattern.LITERAL);
|
||||
private static final String TABLE_PLACEHOLDER = "{table}";
|
||||
|
||||
private static final Pattern TABLE_REPLACE = Pattern.compile(TABLE_PLACEHOLDER, Pattern.LITERAL);
|
||||
|
||||
/**
|
||||
* Set if this DB supports sequences. Note some DB's support both Sequences
|
||||
@@ -53,7 +55,9 @@ public class DbIdentity {
|
||||
if (selectLastInsertedIdTemplate == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!selectLastInsertedIdTemplate.contains(TABLE_PLACEHOLDER)) {
|
||||
return selectLastInsertedIdTemplate;
|
||||
}
|
||||
return TABLE_REPLACE.matcher(selectLastInsertedIdTemplate).replaceAll(Matcher.quoteReplacement(table));
|
||||
}
|
||||
|
||||
|
||||
@@ -1398,4 +1398,10 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return orphanBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL used to fetch the last inserted id value.
|
||||
*/
|
||||
public String getSelectLastInsertedId() {
|
||||
return beanDescriptor.getSelectLastInsertedId(publish);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +182,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
* getGeneratedKeys is not supported.
|
||||
*/
|
||||
private final String selectLastInsertedId;
|
||||
private final String selectLastInsertedIdDraft;
|
||||
|
||||
private final boolean autoTunable;
|
||||
|
||||
@@ -473,6 +474,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
this.sequenceInitialValue = deploy.getSequenceInitialValue();
|
||||
this.sequenceAllocationSize = deploy.getSequenceAllocationSize();
|
||||
this.selectLastInsertedId = deploy.getSelectLastInsertedId();
|
||||
this.selectLastInsertedIdDraft = deploy.getSelectLastInsertedIdDraft();
|
||||
this.concurrencyMode = deploy.getConcurrencyMode();
|
||||
this.updateChangesOnly = deploy.isUpdateChangesOnly();
|
||||
this.indexDefinitions = deploy.getIndexDefinitions();
|
||||
@@ -3086,8 +3088,15 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
* supported.
|
||||
* </p>
|
||||
*/
|
||||
public String getSelectLastInsertedId() {
|
||||
return selectLastInsertedId;
|
||||
public String getSelectLastInsertedId(boolean publish) {
|
||||
return publish ? selectLastInsertedId : selectLastInsertedIdDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this bean uses a SQL select to fetch the last inserted id value.
|
||||
*/
|
||||
public boolean supportsSelectLastInsertedId() {
|
||||
return selectLastInsertedId != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1387,9 +1387,10 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
}
|
||||
|
||||
if (IdType.IDENTITY == desc.getIdType()) {
|
||||
// used when getGeneratedKeys is not supported (SQL Server 2000)
|
||||
// used when getGeneratedKeys is not supported (SQL Server 2000, SAP Hana)
|
||||
String selectLastInsertedId = dbIdentity.getSelectLastInsertedId(desc.getBaseTable());
|
||||
desc.setSelectLastInsertedId(selectLastInsertedId);
|
||||
String selectLastInsertedIdDraft = (!desc.isDraftable()) ? selectLastInsertedId : dbIdentity.getSelectLastInsertedId(desc.getDraftTable());
|
||||
desc.setSelectLastInsertedId(selectLastInsertedId, selectLastInsertedIdDraft);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ public class DeployBeanDescriptor<T> {
|
||||
* Used with Identity columns but no getGeneratedKeys support.
|
||||
*/
|
||||
private String selectLastInsertedId;
|
||||
private String selectLastInsertedIdDraft;
|
||||
|
||||
/**
|
||||
* The concurrency mode for beans of this type.
|
||||
@@ -839,11 +840,16 @@ public class DeployBeanDescriptor<T> {
|
||||
return selectLastInsertedId;
|
||||
}
|
||||
|
||||
public String getSelectLastInsertedIdDraft() {
|
||||
return selectLastInsertedIdDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SQL used to return the last inserted Id.
|
||||
*/
|
||||
public void setSelectLastInsertedId(String selectLastInsertedId) {
|
||||
public void setSelectLastInsertedId(String selectLastInsertedId, String selectLastInsertedIdDraft) {
|
||||
this.selectLastInsertedId = selectLastInsertedId;
|
||||
this.selectLastInsertedIdDraft = selectLastInsertedIdDraft;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,7 @@ public class InsertHandler extends DmlHandler {
|
||||
* A SQL Select used to fetch back the Id where generatedKeys is not
|
||||
* supported.
|
||||
*/
|
||||
private String selectLastInsertedId;
|
||||
private boolean useSelectLastInsertedId;
|
||||
|
||||
/**
|
||||
* Create to handle the insert execution.
|
||||
@@ -79,7 +79,7 @@ public class InsertHandler extends DmlHandler {
|
||||
useGeneratedKeys = true;
|
||||
} else {
|
||||
// use a query to get the last inserted id
|
||||
selectLastInsertedId = meta.getSelectLastInsertedId();
|
||||
useSelectLastInsertedId = meta.supportsSelectLastInsertedId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,8 +117,7 @@ public class InsertHandler extends DmlHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the insert in a normal non batch fashion. Additionally using
|
||||
* getGeneratedKeys if required.
|
||||
* Execute non batched insert additionally using getGeneratedKeys if required.
|
||||
*/
|
||||
@Override
|
||||
public int execute() throws SQLException, OptimisticLockException {
|
||||
@@ -127,7 +126,7 @@ public class InsertHandler extends DmlHandler {
|
||||
// get the auto-increment value back and set into the bean
|
||||
getGeneratedKeys();
|
||||
|
||||
} else if (selectLastInsertedId != null) {
|
||||
} else if (useSelectLastInsertedId) {
|
||||
// fetch back the Id using a query
|
||||
fetchGeneratedKeyUsingSelect();
|
||||
}
|
||||
@@ -167,12 +166,10 @@ public class InsertHandler extends DmlHandler {
|
||||
*/
|
||||
private void fetchGeneratedKeyUsingSelect() throws SQLException {
|
||||
|
||||
Connection conn = transaction.getConnection();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rset = null;
|
||||
try {
|
||||
stmt = conn.prepareStatement(selectLastInsertedId);
|
||||
stmt = transaction.getConnection().prepareStatement(persistRequest.getSelectLastInsertedId());
|
||||
rset = stmt.executeQuery();
|
||||
setGeneratedKey(rset);
|
||||
} finally {
|
||||
|
||||
@@ -38,7 +38,7 @@ public final class InsertMeta {
|
||||
/**
|
||||
* Used for DB that do not support getGeneratedKeys.
|
||||
*/
|
||||
private final String selectLastInsertedId;
|
||||
private final boolean supportsSelectLastInsertedId;
|
||||
|
||||
private final Bindable shadowFKey;
|
||||
|
||||
@@ -69,7 +69,7 @@ public final class InsertMeta {
|
||||
this.sqlNullId = null;
|
||||
this.sqlDraftNullId = null;
|
||||
this.supportsGetGeneratedKeys = false;
|
||||
this.selectLastInsertedId = null;
|
||||
this.supportsSelectLastInsertedId = false;
|
||||
|
||||
} else {
|
||||
// insert sql for db identity or sequence insert
|
||||
@@ -77,11 +77,11 @@ public final class InsertMeta {
|
||||
if (id.getIdentityColumn() == null) {
|
||||
this.identityDbColumns = new String[]{};
|
||||
this.supportsGetGeneratedKeys = false;
|
||||
this.selectLastInsertedId = null;
|
||||
this.supportsSelectLastInsertedId = false;
|
||||
} else {
|
||||
this.identityDbColumns = new String[]{id.getIdentityColumn()};
|
||||
this.supportsGetGeneratedKeys = dbPlatform.getDbIdentity().isSupportsGetGeneratedKeys();
|
||||
this.selectLastInsertedId = desc.getSelectLastInsertedId();
|
||||
this.supportsSelectLastInsertedId = desc.supportsSelectLastInsertedId();
|
||||
}
|
||||
this.sqlNullId = genSql(true, tableName, false);
|
||||
this.sqlDraftNullId = desc.isDraftable() ? genSql(true, draftTableName, true) : sqlNullId;
|
||||
@@ -116,15 +116,11 @@ public final class InsertMeta {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sql that is used to fetch back the last inserted id. This will
|
||||
* return null if it should not be used.
|
||||
* <p>
|
||||
* This is only for DB's that do not support getGeneratedKeys. For MS
|
||||
* SQLServer 2000 this could return "SELECT (at)(at)IDENTITY as id".
|
||||
* </p>
|
||||
* Return true if we should use a SQL query to return the generated key.
|
||||
* This can not be used with JDBC batch mode.
|
||||
*/
|
||||
public String getSelectLastInsertedId() {
|
||||
return selectLastInsertedId;
|
||||
public boolean supportsSelectLastInsertedId() {
|
||||
return supportsSelectLastInsertedId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user