Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ebean-api/src/main/java/io/ebean/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ static Transaction current() {
*/
void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties);

/**
* If set to false (default is true) generated propertes are only set, if it is the version property or have a null value.
* This may be useful in backup & restore scenarios, if you want set WhenCreated/WhenModified.
*/
void setOverwriteGeneratedProperties(boolean overwriteGeneratedProperties);

/**
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ public interface SpiTransaction extends Transaction {
*/
Boolean isUpdateAllLoadedProperties();

/**
* Returns true, if generated properties are overwritten (default) or are only set, if they are null.
*/
boolean isOverwriteGeneratedProperties();

/**
* Return the batchSize specifically set for this transaction or 0.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ public void setUpdateAllLoadedProperties(boolean updateAllLoaded) {
transaction.setUpdateAllLoadedProperties(updateAllLoaded);
}

@Override
public void setOverwriteGeneratedProperties(boolean overwriteGeneratedProperties) {
transaction.setOverwriteGeneratedProperties(overwriteGeneratedProperties);
}

@Override
public boolean isOverwriteGeneratedProperties() {
return transaction.isOverwriteGeneratedProperties();
}

@Override
public Boolean isUpdateAllLoadedProperties() {
return transaction.isUpdateAllLoadedProperties();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,24 +274,30 @@ private void onUpdateGeneratedProperties() {
} else {
// @WhenModified set without invoking interception
Object oldVal = prop.getValue(entityBean);
Object value = generatedProperty.getUpdateValue(prop, entityBean, now());
prop.setValueChanged(entityBean, value);
intercept.setOldValue(prop.propertyIndex(), oldVal);
if (transaction == null || transaction.isOverwriteGeneratedProperties() || oldVal == null) { // version handled above
Object value = generatedProperty.getUpdateValue(prop, entityBean, now());
prop.setValueChanged(entityBean, value);
intercept.setOldValue(prop.propertyIndex(), oldVal);
}
}
}
}

private void onFailedUpdateUndoGeneratedProperties() {
for (BeanProperty prop : beanDescriptor.propertiesGenUpdate()) {
Object oldVal = intercept.origValue(prop.propertyIndex());
prop.setValue(entityBean, oldVal);
if (transaction == null || transaction.isOverwriteGeneratedProperties() || prop.isVersion()) {
Object oldVal = intercept.origValue(prop.propertyIndex());
prop.setValue(entityBean, oldVal);
}
}
}

private void onInsertGeneratedProperties() {
for (BeanProperty prop : beanDescriptor.propertiesGenInsert()) {
Object value = prop.generatedProperty().getInsertValue(prop, entityBean, now());
prop.setValueChanged(entityBean, value);
if (transaction == null || transaction.isOverwriteGeneratedProperties() || prop.isVersion() || prop.getValue(entityBean) == null) {
Object value = prop.generatedProperty().getInsertValue(prop, entityBean, now());
prop.setValueChanged(entityBean, value);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,15 @@ public void setReadOnly(boolean readOnly) {
public void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties) {
}

@Override
public void setOverwriteGeneratedProperties(boolean overwriteGeneratedProperties) {
}

@Override
public boolean isOverwriteGeneratedProperties() {
return true;
}

@Override
public Boolean isUpdateAllLoadedProperties() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
private boolean queryOnly = true;
private boolean localReadOnly;
private Boolean updateAllLoadedProperties;
private boolean overwriteGeneratedProperties = true;
private boolean oldBatchMode;
private boolean batchMode;
private boolean batchOnCascadeMode;
Expand Down Expand Up @@ -448,6 +449,16 @@ public final Boolean isUpdateAllLoadedProperties() {
return updateAllLoadedProperties;
}

@Override
public void setOverwriteGeneratedProperties(boolean overwriteGeneratedProperties) {
this.overwriteGeneratedProperties = overwriteGeneratedProperties;
}

@Override
public boolean isOverwriteGeneratedProperties() {
return overwriteGeneratedProperties;
}

@Override
public final void setBatchMode(boolean batchMode) {
this.batchMode = batchMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ public void setPersistCascade(boolean persistCascade) {
public void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties) {
}

@Override
public void setOverwriteGeneratedProperties(boolean overwriteGeneratedProperties) {
}

@Override
public boolean isOverwriteGeneratedProperties() {
return true;
}

@Override
public void setSkipCache(boolean skipCache) {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.tests.generated;

import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.Transaction;
import io.ebean.xtest.BaseTestCase;
import org.junit.jupiter.api.Test;
import org.tests.model.EGenProps;

import java.time.Instant;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;

Expand Down Expand Up @@ -47,4 +50,42 @@ public void test_insert() {

DB.delete(bean);
}

@Test
public void test_update_no_overwrite() {
EGenProps bean = new EGenProps();
bean.setName("updating");
DB.save(bean);

bean = DB.find(EGenProps.class, bean.getId());
bean.setInstantCreated(Instant.parse("2022-01-01T00:00:00Z"));
bean.setInstantUpdated(Instant.parse("2022-01-02T00:00:00Z"));
try (Transaction txn = DB.beginTransaction()) {
txn.setOverwriteGeneratedProperties(false);
DB.save(bean);
txn.commit();
}

bean = DB.find(EGenProps.class, bean.getId());
assertThat(bean.getInstantCreated()).isEqualTo(Instant.parse("2022-01-01T00:00:00Z"));
assertThat(bean.getInstantUpdated()).isEqualTo(Instant.parse("2022-01-02T00:00:00Z"));
}

@Test
public void test_insert_no_overwrite() {
EGenProps bean = new EGenProps();
try (Transaction txn = DB.beginTransaction()) {
txn.setOverwriteGeneratedProperties(false);
bean.setName("inserting");
bean.setInstantCreated(Instant.parse("2022-01-01T00:00:00Z"));
bean.setInstantUpdated(Instant.parse("2022-01-02T00:00:00Z"));
DB.save(bean);
txn.commit();
}


bean = DB.find(EGenProps.class, bean.getId());
assertThat(bean.getInstantCreated()).isEqualTo(Instant.parse("2022-01-01T00:00:00Z"));
assertThat(bean.getInstantUpdated()).isEqualTo(Instant.parse("2022-01-02T00:00:00Z"));
}
}