historized feature
diff --git a/org.eclipse.osbp.jpa.services.feature/feature.xml b/org.eclipse.osbp.jpa.services.feature/feature.xml
index 81c4ed3..936f12c 100644
--- a/org.eclipse.osbp.jpa.services.feature/feature.xml
+++ b/org.eclipse.osbp.jpa.services.feature/feature.xml
@@ -3,7 +3,8 @@
id="org.eclipse.osbp.jpa.services.feature"
label="%featureName"
version="0.9.0.qualifier"
- provider-name="%providerName">
+ provider-name="%providerName"
+ plugin="org.eclipse.osbp.license">
<description>
%description
diff --git a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedDescriptorWrapper.java b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedDescriptorWrapper.java
index 744095f..c62908a 100644
--- a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedDescriptorWrapper.java
+++ b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedDescriptorWrapper.java
@@ -1,10 +1,14 @@
package org.eclipse.osbp.jpa.services.history;
import java.lang.reflect.Field;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.List;
import javax.persistence.Version;
+import org.eclipse.osbp.runtime.common.annotations.DomainKey;
+import org.eclipse.osbp.runtime.common.annotations.HistDomainKey;
import org.eclipse.osbp.runtime.common.annotations.HistIsCurrent;
import org.eclipse.osbp.runtime.common.annotations.HistIsCustomVersion;
import org.eclipse.osbp.runtime.common.annotations.HistValidUntil;
@@ -18,11 +22,15 @@
private final Class<?> clazz;
private final ClassDescriptor descriptor;
+ private final SimpleDateFormat dateFormat;
private DatabaseMapping versionMapping;
private DatabaseMapping validUntilMapping;
private DatabaseMapping currentMapping;
private DatabaseMapping isCustomVersionMapping;
+ private DatabaseMapping historizedDomainKeyMapping;
+ private DatabaseMapping domainKeyMapping;
+
private DatabaseMapping idMapping;
private ClassDescriptor uuidHistDescriptor;
private DatabaseMapping id_idMapping;
@@ -32,6 +40,9 @@
this.clazz = descriptor.getJavaClass();
this.descriptor = descriptor;
+ // later may be controlled by the descriptor
+ dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+
// find the ID String field by the descriptor
List<DatabaseField> pk = descriptor.getPrimaryKeyFields();
for (DatabaseMapping mapping : descriptor.getMappings()) {
@@ -47,6 +58,8 @@
Field validUntilField = BeanUtils.getField(clazz, HistValidUntil.class);
Field currentHist = BeanUtils.getField(clazz, HistIsCurrent.class);
Field isCustomVersion = BeanUtils.getField(clazz, HistIsCustomVersion.class);
+ Field historizedDomainKeyField = BeanUtils.getField(clazz, HistDomainKey.class);
+ Field domainKeyField = BeanUtils.getField(clazz, DomainKey.class);
id_idMapping = uuidHistDescriptor.getMappingForAttributeName("id");
id_validFromMapping = uuidHistDescriptor.getMappingForAttributeName("validFrom");
@@ -54,6 +67,9 @@
validUntilMapping = descriptor.getMappingForAttributeName(validUntilField.getName());
currentMapping = descriptor.getMappingForAttributeName(currentHist.getName());
isCustomVersionMapping = descriptor.getMappingForAttributeName(isCustomVersion.getName());
+ versionMapping = descriptor.getMappingForAttributeName(versionField.getName());
+ historizedDomainKeyMapping = descriptor.getMappingForAttributeName(historizedDomainKeyField.getName());
+ domainKeyMapping = descriptor.getMappingForAttributeName(domainKeyField.getName());
}
public String getIdAttName() {
@@ -84,6 +100,10 @@
return isCustomVersionMapping.getAttributeName();
}
+ public String getHistorizedDomainKeyAttName() {
+ return historizedDomainKeyMapping.getAttributeName();
+ }
+
public UUIDHist getID(Object obj) {
return (UUIDHist) idMapping.getAttributeValueFromObject(obj);
}
@@ -120,6 +140,10 @@
return (boolean) isCustomVersionMapping.getAttributeValueFromObject(obj);
}
+ public String getHistorizedDomainKey(Object obj) {
+ return (String) historizedDomainKeyMapping.getAttributeValueFromObject(obj);
+ }
+
public Class<?> getEntityClass() {
return descriptor.getJavaClass();
}
@@ -164,4 +188,21 @@
isCustomVersionMapping.setAttributeValueInObject(obj, value);
}
+ public void setHistorizedDomainKey(Object obj, String value) {
+ historizedDomainKeyMapping.setAttributeValueInObject(obj, value);
+ }
+
+ public void applyHistorizedDomainKey(Object obj) {
+ if (domainKeyMapping == null) {
+ return;
+ }
+
+ String domainKey = (String) domainKeyMapping.getAttributeValueFromObject(obj);
+ Date date = new Date(getId_ValidFrom(obj));
+
+ String histDomainKey = domainKey + "-" + dateFormat.format(date);
+ setHistorizedDomainKey(obj, histDomainKey);
+
+ }
+
}
diff --git a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedObjectWrapper.java b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedObjectWrapper.java
index a8173d9..0d077ff 100644
--- a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedObjectWrapper.java
+++ b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedObjectWrapper.java
@@ -24,8 +24,6 @@
return delegate.getVersionAttName();
}
-
-
public String getId_IdAttName() {
return delegate.getId_IdAttName();
}
@@ -106,4 +104,20 @@
delegate.setCustomVersion(obj, value);
}
+ public String getHistorizedDomainKeyAttName() {
+ return delegate.getHistorizedDomainKeyAttName();
+ }
+
+ public String getHistorizedDomainKey() {
+ return delegate.getHistorizedDomainKey(obj);
+ }
+
+ public void setHistorizedDomainKey(String value) {
+ delegate.setHistorizedDomainKey(obj, value);
+ }
+
+ public void applyHistorizedDomainKey() {
+ delegate.applyHistorizedDomainKey(obj);
+ }
+
}
diff --git a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedQueryRedirector.java b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedQueryRedirector.java
index 96168f5..286587d 100644
--- a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedQueryRedirector.java
+++ b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistorizedQueryRedirector.java
@@ -17,17 +17,26 @@
import org.eclipse.persistence.queries.WriteObjectQuery;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Manages the versioning of historized and timedependent entities.
*/
@SuppressWarnings("serial")
public class HistorizedQueryRedirector implements QueryRedirector {
+ protected static Logger logger = LoggerFactory.getLogger(HistorizedQueryRedirector.class);
@Override
public Object invokeQuery(DatabaseQuery query, Record arguments, Session session) {
WriteObjectQuery writeObjectQuery = (WriteObjectQuery) query;
-
+
+ logger.debug("historized changes {}", writeObjectQuery.getObjectChangeSet().getChanges());
+
+ if(writeObjectQuery instanceof UpdateObjectQuery) {
+ return writeObjectQuery.getObject();
+ }
+
Object persistedObj = writeObjectQuery.getObject();
// the object that was persisted / merged
@@ -35,32 +44,40 @@
HistorizedObjectWrapper persistedObjWrapper = new HistorizedObjectWrapper(writeObjectQuery.getDescriptor(),
persistedObj);
- if (persistedObjWrapper.getVersion() > 1) {
- throw new IllegalArgumentException(
- "Version must be 0. Changing historized records is not allowed: " + persistedObj.toString());
- }
+// if (persistedObjWrapper.getVersion() > 1) {
+// throw new IllegalArgumentException(
+// "Version must be 0. Changing historized records is not allowed: " + persistedObj.toString());
+// }
Object current = getCurrent(persistedObjWrapper, (AbstractSession) session);
if (current == null) {
persistedObjWrapper.setId_ValidFrom(createNow(persistedObjWrapper));
persistedObjWrapper.setValidUntil(getMaxDate());
persistedObjWrapper.setCurrentHist(true);
+
+ persistedObjWrapper.applyHistorizedDomainKey();
writeObjectQuery.setDoNotRedirect(true);
- Object newAdr = writeObjectQuery.execute((AbstractSession) session, (AbstractRecord) arguments);
- return newAdr;
+ return writeObjectQuery.execute((AbstractSession) session, (AbstractRecord) arguments);
} else {
// sleep 1ms for minimum time intervall between historized records
try {
Thread.sleep(1);
- } catch (InterruptedException e) {
+ } catch (InterruptedException e) { // NOSONAR
}
// update the address to be historized
long now = createNow(persistedObjWrapper);
Object histCurrentObj = getCurrentManaged(
new HistorizedObjectWrapper(writeObjectQuery.getDescriptor(), current), (AbstractSession) session);
+ Object histCurrentObjClone = null;
+ try {
+ histCurrentObjClone = histCurrentObj.getClass().newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ logger.error("{}", e);
+ }
+ query.getDescriptor().getObjectBuilder().copyInto(histCurrentObj, histCurrentObjClone);
// the current object in database with flag histCurrent = true
//
@@ -72,24 +89,29 @@
return persistedObj;
}
+ // update the old record
+ //
histCurrentObjWrapper.setCurrentHist(false);
histCurrentObjWrapper.setValidUntil(now);
UpdateObjectQuery updateCurrent = new UpdateObjectQuery(histCurrentObj);
+ updateCurrent.setBackupClone(histCurrentObjClone);
updateCurrent.setDoNotRedirect(true);
updateCurrent.setIsUserDefined(true);
updateCurrent.execute((AbstractSession) session, (AbstractRecord) arguments);
+ // insert the new record
+ //
persistedObjWrapper.setId_ValidFrom(now);
persistedObjWrapper.setValidUntil(getMaxDate());
persistedObjWrapper.setCurrentHist(true);
persistedObjWrapper.setVersion((int) 0);
+ persistedObjWrapper.applyHistorizedDomainKey();
InsertObjectQuery insertObjectQ = new InsertObjectQuery(persistedObj);
insertObjectQ.setIsUserDefined(true);
insertObjectQ.setDoNotRedirect(true);
- Object newAdr = insertObjectQ.execute((AbstractSession) session, (AbstractRecord) arguments);
- return newAdr;
+ return insertObjectQ.execute((AbstractSession) session, (AbstractRecord) arguments);
}
}
@@ -114,7 +136,7 @@
rq.dontCheckCache();
rq.dontMaintainCache();
- Object current = (Object) rq.executeInUnitOfWork(uow, EmptyRecord.getEmptyRecord());
+ Object current = rq.executeInUnitOfWork(uow, EmptyRecord.getEmptyRecord());
uow.clearForClose(true);
return current;
@@ -123,14 +145,13 @@
private Object getCurrentManaged(HistorizedObjectWrapper wrapper, AbstractSession session) {
ReadObjectQuery rq = new ReadObjectQuery(wrapper.getEntityClass());
+ rq.conformResultsInUnitOfWork();
ExpressionBuilder eb = rq.getExpressionBuilder();
Expression exp = eb.get(wrapper.getIdAttName()).equal(wrapper.getID());
rq.setSelectionCriteria(exp);
- Object current = rq.execute(session, EmptyRecord.getEmptyRecord());
-
- return current;
+ return rq.execute(session, EmptyRecord.getEmptyRecord());
}
private long getMaxDate() {
diff --git a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistoryFacade.java b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistoryFacade.java
index 0679bdf..1a8a6c6 100644
--- a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistoryFacade.java
+++ b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/history/HistoryFacade.java
@@ -37,6 +37,7 @@
@SuppressWarnings("rawtypes")
public class HistoryFacade {
+ private static final String HISTORIZED_POSTFIX = "_HIST";
private static Map timeOffsetsMap = new IdentityHashMap();
protected HistoryFacade() {
@@ -121,7 +122,7 @@
long endTime = System.currentTimeMillis();
long jvmTime = (endTime - startTime) / 2 + startTime;
long offset = databaseTime.getTime() - jvmTime;
- timeOffsetsMap.put(rootSession, new Long(offset));
+ timeOffsetsMap.put(rootSession, offset);
return jvmTime + offset;
}
}
@@ -133,14 +134,14 @@
* the descriptors.
*/
@SuppressWarnings("unchecked")
- public static void generateHistoricalTableDefinitions(TableCreator creator, Session session) {
+ public static void generateHistoricalTableDefinitions(TableCreator creator, Session session) { //NOSONAR
// First add all table definitions to a hashtable.
Map<String, TableDefinition> tableDefinitions = new HashMap(creator.getTableDefinitions().size());
for (TableDefinition def : creator.getTableDefinitions()) {
tableDefinitions.put(def.getFullName(), def);
}
- Set<String> generatedTables = new HashSet<String>();
+ Set<String> generatedTables = new HashSet<>();
for (ClassDescriptor descriptor : session.getDescriptors().values()) {
HistoryPolicy policy = descriptor.getHistoryPolicy();
if (policy != null) {
@@ -161,7 +162,7 @@
policy = m2mMapping.getHistoryPolicy();
if (policy != null) {
String name = m2mMapping.getRelationTableName();
- String histName = (String)policy.getHistoryTableNames().get(0);
+ String histName = policy.getHistoryTableNames().get(0);
if (!generatedTables.contains(histName)) {
generatedTables.add(histName);
TableDefinition def = tableDefinitions.get(name);
@@ -173,7 +174,7 @@
policy = dcMapping.getHistoryPolicy();
if (policy != null) {
String name = dcMapping.getReferenceTableName();
- String histName = (String)policy.getHistoryTableNames().get(0);
+ String histName = policy.getHistoryTableNames().get(0);
if (!generatedTables.contains(histName)) {
generatedTables.add(histName);
TableDefinition def = tableDefinitions.get(name);
@@ -212,9 +213,9 @@
String name = table.getQualifiedNameDelimited(platform);
String historicalName;
if(table.shouldUseDelimiters()) {
- historicalName = name.substring(0, name.length() - 1) + "_HIST" + Helper.getDefaultEndDatabaseDelimiter();
+ historicalName = name.substring(0, name.length() - 1) + HISTORIZED_POSTFIX + Helper.getDefaultEndDatabaseDelimiter();
} else {
- historicalName = name + "_HIST";
+ historicalName = name + HISTORIZED_POSTFIX;
}
policy.addHistoryTableName(name, historicalName);
}
@@ -228,14 +229,14 @@
ManyToManyMapping m2mMapping = (ManyToManyMapping)mapping;
policy = (HistoryPolicy)basePolicy.clone();
policy.addHistoryTableName(m2mMapping.getRelationTableName() +
- "_HIST");
+ HISTORIZED_POSTFIX);
m2mMapping.setHistoryPolicy(policy);
} else if (mapping instanceof DirectCollectionMapping) {
DirectCollectionMapping dcMapping =
(DirectCollectionMapping)mapping;
policy = (HistoryPolicy)basePolicy.clone();
policy.addHistoryTableName(dcMapping.getReferenceTableName() +
- "_HIST");
+ HISTORIZED_POSTFIX);
dcMapping.setHistoryPolicy(policy);
}
}
diff --git a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/listener/EntityInfoListener.java b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/listener/EntityInfoListener.java
index 9b50ed6..8983910 100644
--- a/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/listener/EntityInfoListener.java
+++ b/org.eclipse.osbp.jpa.services/src/org/eclipse/osbp/jpa/services/listener/EntityInfoListener.java
@@ -27,6 +27,9 @@
String user = (String) session.get("userId");
BeanUtils.setUpdateUser(bean, user);
BeanUtils.setUpdateAt(bean, new Date());
+ if(BeanUtils.isHistorized(bean.getClass())) {
+ System.out.println("hist");
+ }
}
}
}