WhoCreated, WhoModified on OneToMany connections. (#942)

* WhoCreated, WhoModified on OneToMany connections.

* PostgreSQL table name fix in tests.
This commit is contained in:
Nagy Vilmos
2017-01-11 20:54:20 +13:00
committed by Rob Bygrave
parent e49c42302a
commit 8fd04807c7
7 changed files with 272 additions and 14 deletions
@@ -140,6 +140,21 @@ public class AnnotationFields extends AnnotationParser {
if (formula != null) {
prop.setSqlFormula(formula.select(), formula.join());
}
initWhoCreated(prop);
initWhoModified(prop);
}
private void initWhoModified(DeployBeanProperty prop) {
if (get(prop, WhoModified.class) != null) {
generatedPropFactory.setWhoModified(prop);
}
}
private void initWhoCreated(DeployBeanProperty prop) {
if (get(prop, WhoCreated.class) != null) {
generatedPropFactory.setWhoCreated(prop);
}
}
private void readField(DeployBeanProperty prop) {
@@ -282,12 +297,8 @@ public class AnnotationFields extends AnnotationParser {
generatedPropFactory.setUpdateTimestamp(prop);
}
if (get(prop, WhoCreated.class) != null) {
generatedPropFactory.setWhoCreated(prop);
}
if (get(prop, WhoModified.class) != null) {
generatedPropFactory.setWhoModified(prop);
}
initWhoCreated(prop);
initWhoModified(prop);
if (get(prop, HistoryExclude.class) != null) {
prop.setExcludedFromHistory();
@@ -3,8 +3,11 @@ package io.ebeaninternal.server.persist.dmlbind;
import io.ebean.bean.EntityBean;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.id.ImportedId;
import io.ebeaninternal.server.persist.dml.DmlMode;
import io.ebeaninternal.server.persist.dml.GenerateDmlRequest;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
import java.util.List;
@@ -17,10 +20,14 @@ public class BindableAssocOne implements Bindable {
private final BeanPropertyAssocOne<?> assocOne;
private final ImportedId importedId;
private final DmlMode dmlMode;
private final GeneratedProperty generatedProperty;
public BindableAssocOne(BeanPropertyAssocOne<?> assocOne) {
public BindableAssocOne(BeanPropertyAssocOne<?> assocOne, DmlMode mode) {
this.assocOne = assocOne;
this.importedId = assocOne.getImportedId();
this.dmlMode = mode;
this.generatedProperty = assocOne.getGeneratedProperty();
}
public String toString() {
@@ -33,7 +40,9 @@ public class BindableAssocOne implements Bindable {
}
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
if (request.isAddToUpdate(assocOne)) {
if (generatedProperty != null && generatedProperty.includeInAllUpdates()) {
list.add(this);
} else if (request.isAddToUpdate(assocOne)) {
list.add(this);
}
}
@@ -43,8 +52,41 @@ public class BindableAssocOne implements Bindable {
}
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
if (generatedProperty != null) {
bindGeneratedProperty(request, bean);
} else {
bindNotGeneratedProperty(request, bean);
}
}
private void bindGeneratedProperty(BindableRequest request, EntityBean bean) throws SQLException {
if (DmlMode.INSERT.equals(dmlMode) && generatedProperty.includeInInsert()) {
bindGeneratedInsert(request, bean);
} else if (DmlMode.UPDATE.equals(dmlMode) && generatedProperty.includeInAllUpdates()) {
bindGeneratedUpdate(request, bean);
}
}
private void bindGeneratedUpdate(BindableRequest request, EntityBean bean) throws SQLException {
Object objectValue = generatedProperty.getUpdateValue(assocOne, bean, request.now());
EntityBean generatedValue = castToEntityBean(objectValue);
assocOne.setValueChanged(bean, generatedValue);
registerDeferred(request, bean, generatedValue);
}
private void bindGeneratedInsert(BindableRequest request, EntityBean bean) throws SQLException {
Object objectValue = generatedProperty.getInsertValue(assocOne, bean, request.now());
EntityBean generatedValue = castToEntityBean(objectValue);
assocOne.setValue(bean, generatedValue);
registerDeferred(request, bean, generatedValue);
}
private void bindNotGeneratedProperty(BindableRequest request, EntityBean bean) throws SQLException {
EntityBean assocBean = (EntityBean) assocOne.getValue(bean);
registerDeferred(request, bean, assocBean);
}
private void registerDeferred(BindableRequest request, EntityBean bean, EntityBean assocBean) throws SQLException {
Object boundValue = importedId.bind(request, assocBean);
if (boundValue == null && assocBean != null) {
// this is the scenario for a derived foreign key
@@ -55,4 +97,15 @@ public class BindableAssocOne implements Bindable {
}
}
@Nullable
private EntityBean castToEntityBean(Object objectValue) {
EntityBean generatedValue;
if (objectValue instanceof EntityBean || objectValue == null) {
generatedValue = (EntityBean) objectValue;
} else {
throw new IllegalStateException("Bean " + objectValue.getClass() + " is not enhanced?");
}
return generatedValue;
}
}
@@ -35,7 +35,7 @@ public class FactoryAssocOnes {
}
break;
}
list.add(new BindableAssocOne(one));
list.add(new BindableAssocOne(one, mode));
}
}
}
@@ -12,7 +12,7 @@ public class MyCurrentUserProvider implements CurrentUserProvider {
/**
* Do not do this yourself - this is for testing purposes.
*/
private static String userId = DEFAULT;
private static Object userId = DEFAULT;
@Override
@@ -21,7 +21,7 @@ public class MyCurrentUserProvider implements CurrentUserProvider {
return userId;
}
public static void setUserId(String value) {
public static void setUser(Object value) {
userId = value;
}
@@ -5,9 +5,12 @@ import io.ebean.Ebean;
import io.ebean.MyCurrentUserProvider;
import org.tests.model.EWhoProps;
import org.junit.Test;
import org.tests.model.generated.User;
import org.tests.model.generated.WhoPropsOneToMany;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
public class TestGeneratedWho extends BaseTestCase {
@@ -17,7 +20,7 @@ public class TestGeneratedWho extends BaseTestCase {
EWhoProps bean = new EWhoProps();
bean.setName("one");
MyCurrentUserProvider.setUserId("INSERT_WHO_1");
MyCurrentUserProvider.setUser("INSERT_WHO_1");
Ebean.save(bean);
assertEquals("one", bean.getName());
@@ -26,7 +29,7 @@ public class TestGeneratedWho extends BaseTestCase {
assertNotNull(bean.getWhenCreated());
assertNotNull(bean.getWhenModified());
MyCurrentUserProvider.setUserId("UPDATE_WHO_1");
MyCurrentUserProvider.setUser("UPDATE_WHO_1");
bean.setName("two");
Ebean.save(bean);
@@ -34,7 +37,7 @@ public class TestGeneratedWho extends BaseTestCase {
assertEquals("INSERT_WHO_1", bean.getWhoCreated());
assertEquals("UPDATE_WHO_1", bean.getWhoModified());
MyCurrentUserProvider.setUserId("UPDATE_WHO_2");
MyCurrentUserProvider.setUser("UPDATE_WHO_2");
bean.setName("three");
Ebean.save(bean);
@@ -43,4 +46,60 @@ public class TestGeneratedWho extends BaseTestCase {
MyCurrentUserProvider.resetToDefault();
}
@Test
public void insertOneToManyWhoCreated() {
User creator = new User("jack");
User maintainer01 = new User("jill");
User maintainer02 = new User("joe");
Ebean.save(creator);
Ebean.save(maintainer01);
Ebean.save(maintainer02);
WhoPropsOneToMany bean = new WhoPropsOneToMany();
bean.setName("one");
MyCurrentUserProvider.setUser(creator);
Ebean.save(bean);
assertNotNull(bean.getWhoCreated());
assertEquals(creator.getId(), bean.getWhoCreated().getId());
assertEquals(creator.getId(), bean.getWhoModified().getId());
MyCurrentUserProvider.setUser(maintainer01);
bean.setName("two");
Ebean.save(bean);
assertEquals("two", bean.getName());
assertEquals(creator.getId(), bean.getWhoCreated().getId());
assertEquals(maintainer01.getId(), bean.getWhoModified().getId());
MyCurrentUserProvider.setUser(maintainer02);
bean.setName("three");
Ebean.save(bean);
assertEquals(creator.getId(), bean.getWhoCreated().getId());
assertEquals(maintainer02.getId(), bean.getWhoModified().getId());
MyCurrentUserProvider.resetToDefault();
}
@Test
public void insertNullIntoOneToManyWhoCreated() {
User creator = new User("jack");
Ebean.save(creator);
WhoPropsOneToMany bean = new WhoPropsOneToMany();
bean.setName("one");
bean.setWhoCreated(creator);
bean.setWhoModified(creator);
MyCurrentUserProvider.setUser(null);
Ebean.save(bean);
assertNull(bean.getWhoCreated());
assertNull(bean.getWhoModified());
MyCurrentUserProvider.resetToDefault();
}
}
@@ -0,0 +1,39 @@
package org.tests.model.generated;
import javax.persistence.*;
/**
* @author Vilmos Nagy <vilmos.nagy@outlook.com>
*/
@Entity
@Table(name = "g_user")
public class User {
@Id
final Long id;
@Version
final Long version;
@Basic
final String username;
public User(String username) {
this.id = null;
this.version = null;
this.username = username;
}
public Long getId() {
return id;
}
public Long getVersion() {
return version;
}
public String getUsername() {
return username;
}
}
@@ -0,0 +1,96 @@
package org.tests.model.generated;
import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified;
import io.ebean.annotation.WhoCreated;
import io.ebean.annotation.WhoModified;
import javax.persistence.*;
import java.sql.Timestamp;
/**
* @author Vilmos Nagy <vilmos.nagy@outlook.com>
*/
@Entity
@Table(name = "g_who_props_otm")
public class WhoPropsOneToMany {
@Id
Long id;
@Version
Long version;
@WhenCreated
Timestamp whenCreated;
@WhenModified
Timestamp whenModified;
@ManyToOne
@WhoCreated
User whoCreated;
@ManyToOne
@WhoModified
User whoModified;
@Basic
String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public Timestamp getWhenCreated() {
return whenCreated;
}
public void setWhenCreated(Timestamp whenCreated) {
this.whenCreated = whenCreated;
}
public Timestamp getWhenModified() {
return whenModified;
}
public void setWhenModified(Timestamp whenModified) {
this.whenModified = whenModified;
}
public User getWhoCreated() {
return whoCreated;
}
public void setWhoCreated(User whoCreated) {
this.whoCreated = whoCreated;
}
public User getWhoModified() {
return whoModified;
}
public void setWhoModified(User whoModified) {
this.whoModified = whoModified;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}