# HG changeset patch # User casties # Date 1472204561 -7200 # Node ID e52f593f9e0dd07dabdc745b34c7176ea2f82fbe # Parent 9c54842f5e8658244c149e455c21642fda1f2a98 new transaction logger "openmind.transactionlog" logging entity save actions and their data. more comments in code. diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/cache/WrapperService.java --- a/src/main/java/org/mpi/openmind/cache/WrapperService.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/cache/WrapperService.java Fri Aug 26 11:42:41 2016 +0200 @@ -576,15 +576,15 @@ return rel; } - /* - * public Entity saveDefinition(Entity def, String user){ long start = - * System.currentTimeMillis(); def.setObjectClass(Node.TYPE_TBOX); - * def.setUser(user); + /** + * Save the given entity as a separate new entity with a new ID. + * + * Keeps attributes and relations as copies. * - * boolean b = this.searchServ.saveEntity(def); - * this.cache.saveDefinition(def); - * logger.info("saveEntityAsNew - execution time[ms]: " + - * (System.currentTimeMillis() - start)); return (Entity)def.clone(); } + * @param entity + * @param user + * @return + * @throws Exception */ public Entity saveEntityAsNew(Entity entity, String user) throws Exception { long start = System.currentTimeMillis(); @@ -647,6 +647,15 @@ } + /** + * Returns if this entity has wrong relations. + * + * Wrong are source relations whose target doesn't exist. + * Similarly for target relations. + * + * @param ent + * @return + */ private boolean hasWrongRelations(Entity ent) { for (Relation srcRel : ent.getSourceRelations()) { if (getEntityById(srcRel.getTargetId()) == null) { @@ -662,28 +671,33 @@ return false; } - private Entity removeWrongRelations(Entity ent) { - - for (Relation srcRel : new ArrayList(ent.getSourceRelations())) { - if (srcRel.getTargetId() == null || getEntityByIdReadOnly(srcRel.getTargetId()) == null) { - ent.getSourceRelations().remove(srcRel); - logger.error( - "Inconsistency detected saving entity [" - + ent.getId() + "] " + srcRel.toString()); - } - } - - for (Relation tarRel : new ArrayList(ent.getTargetRelations())) { - if (tarRel.getSourceId() == null || getEntityByIdReadOnly(tarRel.getSourceId()) == null) { - ent.getTargetRelations().remove(tarRel); - logger.error( - "Inconsistency detected saving entity [" - + ent.getId() + "] " + tarRel.toString()); - } - } + /** + * Remove wrong relations from this entity. + * + * Wrong are source relations whose target is null or doesn't exist. + * Similarly for target relations. + * + * @param ent + * @return + */ + private Entity removeWrongRelations(Entity ent) { - return ent; - } + for (Relation srcRel : new ArrayList(ent.getSourceRelations())) { + if (srcRel.getTargetId() == null || getEntityByIdReadOnly(srcRel.getTargetId()) == null) { + ent.getSourceRelations().remove(srcRel); + logger.error("Inconsistency detected saving entity [" + ent.getId() + "] " + srcRel.toString()); + } + } + + for (Relation tarRel : new ArrayList(ent.getTargetRelations())) { + if (tarRel.getSourceId() == null || getEntityByIdReadOnly(tarRel.getSourceId()) == null) { + ent.getTargetRelations().remove(tarRel); + logger.error("Inconsistency detected saving entity [" + ent.getId() + "] " + tarRel.toString()); + } + } + + return ent; + } public Attribute getDefAttributeByOwnValue(String defOC, String attOW) { for (Attribute att : this.cache.getDefAttributes(defOC)) { diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/repository/bo/Attribute.java --- a/src/main/java/org/mpi/openmind/repository/bo/Attribute.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/repository/bo/Attribute.java Fri Aug 26 11:42:41 2016 +0200 @@ -1,6 +1,7 @@ package org.mpi.openmind.repository.bo; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @@ -9,6 +10,7 @@ import javax.persistence.Entity; import javax.persistence.Transient; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @@ -203,6 +205,7 @@ } return 0; } + @Override public String toString() { String rowIdString = (this.getRowId() == null) ? "" : "rowId=" + this.getRowId() + ", "; @@ -210,4 +213,34 @@ return "Attribute[" + rowIdString + idString + "source=" + this.getSourceId() + ", name=" + this.getObjectClass() + ", ownValue=" + this.getOwnValue() + ", sysStatus=" + this.getSystemStatus() + "]"; } + + /** + * Returns a String representation with base64-encoded own-value. + * + * To be used for the transaction log. + * + * @return + */ + public String toEncString() { + try { + String es = "ATTRIBUTE[" + + "id=\"" + this.getId() + "\", " + + "row-id=\"" + this.getRowId() + "\", " + + "name=\"" + this.getObjectClass() + "\", " + + "content-type=\"" + this.getContentType() + "\", " + + "source-id=\"" + this.getSourceId() + "\", " + + "source-mtime=\"" + this.getSourceModif() + "\", " + + "source-oc=\"" + this.getSourceObjectClass() + "\", " + + "mtime=\"" + this.getModificationTime() + "\", " + + "version=\"" + this.getVersion() + "\", " + + "user=\"" + this.getUser() + "\", " + + "public=\"" + this.getIsPublic() + "\", " + + "b64-value=\"" + ((this.getOwnValue() != null) ? Base64.encodeBase64String(this.getOwnValue().getBytes("UTF-8")) : "") + "\"]"; + return es; + } catch (UnsupportedEncodingException e) { + // this shouldn't happen + e.printStackTrace(); + } + return "!!!ENCODING-ERROR!!!"; + } } diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/repository/bo/Entity.java --- a/src/main/java/org/mpi/openmind/repository/bo/Entity.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/repository/bo/Entity.java Fri Aug 26 11:42:41 2016 +0200 @@ -1,12 +1,14 @@ package org.mpi.openmind.repository.bo; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import javax.persistence.DiscriminatorValue; import javax.persistence.Transient; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.hibernate.annotations.Cache; @@ -783,6 +785,9 @@ } } + /** + * Sets the ID of the entity and its attributes and relations to null. + */ public void resetId() { this.setId(null); for (Attribute att : this.attributes) { @@ -921,6 +926,9 @@ } } + /** + * Set the system_status of this Entity and its attributes and relations. + */ @Override public void setSystemStatus(String status) { super.setSystemStatus(status); @@ -977,6 +985,32 @@ ", type=" + this.getType() + " att.size=" + this.attributes.size() + "]"; } + /** + * Returns a String representation with base64-encoded own-value. + * + * To be used for the transaction log. + * + * @return + */ + public String toEncString() { + try { + String es = "ENTITY[" + + "id=\"" + this.getId() + "\", " + + "row-id=\"" + this.getRowId() + "\", " + + "object-class=\"" + this.getObjectClass() + "\", " + + "mtime=\"" + this.getModificationTime() + "\", " + + "version=\"" + this.getVersion() + "\", " + + "user=\"" + this.getUser() + "\", " + + "public=\"" + this.getIsPublic() + "\", " + + "b64-value=\"" + ((this.getOwnValue() != null) ? Base64.encodeBase64String(this.getOwnValue().getBytes("UTF-8")) : "") + "\"]"; + return es; + } catch (UnsupportedEncodingException e) { + // this shouldn't happen + e.printStackTrace(); + } + return "!!!ENCODING-ERROR!!!"; + } + public String getShortString(){ return "[" + this.getId() + "] " + this.getOwnValue(); } diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/repository/bo/Node.java --- a/src/main/java/org/mpi/openmind/repository/bo/Node.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/repository/bo/Node.java Fri Aug 26 11:42:41 2016 +0200 @@ -267,6 +267,11 @@ return systemStatus; } + /** + * Set the system_status of this Node. + * + * @param systemStatus + */ public void setSystemStatus(String systemStatus) { this.systemStatus = systemStatus; } diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/repository/bo/Relation.java --- a/src/main/java/org/mpi/openmind/repository/bo/Relation.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/repository/bo/Relation.java Fri Aug 26 11:42:41 2016 +0200 @@ -1,6 +1,7 @@ package org.mpi.openmind.repository.bo; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @@ -8,6 +9,7 @@ import javax.persistence.DiscriminatorValue; import javax.persistence.Transient; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @@ -257,7 +259,40 @@ "sysStatus=" + this.getSystemStatus() + "]"; } - @Override + /** + * Returns a String representation with base64-encoded own-value. + * + * To be used for the transaction log. + * + * @return + */ + public String toEncString() { + try { + String es = "RELATION[" + + "id=\"" + this.getId() + "\", " + + "row-id=\"" + this.getRowId() + "\", " + + "object_class=\"" + this.getObjectClass() + "\", " + + "source-id=\"" + this.getSourceId() + "\", " + + "source-mtime=\"" + this.getSourceModif() + "\", " + + "source-oc=\"" + this.getSourceObjectClass() + "\", " + + "target-id=\"" + this.getTargetId() + "\", " + + "target-mtime=\"" + this.getTargetModif() + "\", " + + "target-oc=\"" + this.getTargetObjectClass() + "\", " + + "mtime=\"" + this.getModificationTime() + "\", " + + "version=\"" + this.getVersion() + "\", " + + "user=\"" + this.getUser() + "\", " + + "public=\"" + this.getIsPublic() + "\", " + + "b64-value=\"" + ((this.getOwnValue() != null) ? Base64.encodeBase64String(this.getOwnValue().getBytes("UTF-8")) : "") + "\"]"; + return es; + } catch (UnsupportedEncodingException e) { + // this shouldn't happen + e.printStackTrace(); + } + return "!!!ENCODING-ERROR!!!"; + } + + + @Override public int compareTo(Relation e) { if(e == null) return 1; diff -r 9c54842f5e86 -r e52f593f9e0d src/main/java/org/mpi/openmind/repository/services/AbstractPersistenceService.java --- a/src/main/java/org/mpi/openmind/repository/services/AbstractPersistenceService.java Thu Aug 25 11:29:47 2016 +0200 +++ b/src/main/java/org/mpi/openmind/repository/services/AbstractPersistenceService.java Fri Aug 26 11:42:41 2016 +0200 @@ -25,16 +25,19 @@ */ public abstract class AbstractPersistenceService { - private ConfigurationService configurationService; + private ConfigurationService configurationService; private OwnValueGenerator ownValueGenerator; private final static String NODE_SEQUENCE = "nodeSequence"; - private static Logger logger = Logger - .getLogger(AbstractPersistenceService.class); + private static Logger logger = Logger.getLogger(AbstractPersistenceService.class); + + public static final String TRANSACTION_LOGGER = "openmind.transactionlog"; - private boolean importModus = false; + private static Logger txLog = Logger.getLogger(TRANSACTION_LOGGER); + + private boolean importMode = false; /* * static { logger.setLevel(Level.DEBUG); PatternLayout layout = new @@ -562,54 +565,17 @@ Entity previousEntity = previousEntityList.get(0); logger.info("Saving previous entity: " + previousEntity); - this.savePreviousEntity(session, previousEntity); + this.persistEntityAsPrevious(session, previousEntity); } } session.getTransaction().commit(); } - /* - * public void removeEntity(Long entId, String type) { - * logger.info("Deleting entity [ID=" + entId + ", type=" + type + - * "]. But keeping history in DB."); Session session = - * HibernateUtil.getSessionFactory().getCurrentSession(); - * session.getTransaction().begin(); - * - * if (entId != null) { List previousEntityList = - * this.getEntities(session, entId, Node.SYS_STATUS_CURRENT_VERSION, type, - * null); if (previousEntityList.size() > 0) { if (previousEntityList.size() - * > 1) { System.err .println( - * "[PersistenceService.saveEntity] found more than one current entities!"); - * } - * - * Entity previousEntity = previousEntityList.get(0); - * logger.info("Saving previous entity: " + previousEntity); - * this.savePreviousEntity(session, previousEntity); } } } - */ - - public void savePreviousEntity(Entity entity) throws Exception { - - Session session = HibernateUtil.getSessionFactory().getCurrentSession(); - session.getTransaction().begin(); - - if (entity.getId() != null) { - List previousEntityList = this.getEntities(session, - entity.getId(), Node.SYS_STATUS_CURRENT_VERSION, - entity.getType(), null, false); - if (previousEntityList.size() > 0) { - if (previousEntityList.size() > 1) { - logger.error("[PersistenceService.saveEntity] found more than one current entities!"); - } - Entity previousEntity = previousEntityList.get(0); - logger.debug("Saving previous entity: " + previousEntity); - this.savePreviousEntity(session, previousEntity); - } - } - this.saveCurrentEntity(session, entity, null); - session.getTransaction().commit(); - } /** + * Save the entity to the database. + * + * Creates a new version of the entity. Runs in a transaction. * * @param entity * @return @@ -625,6 +591,15 @@ } + /** + * Save the entity to the database using the given session. + * + * Creates a new version and sets the existing entity to PREVIOUS_VERSION. + * + * @param session + * @param entity + * @throws Exception + */ private void saveEntity0(Session session, Entity entity) throws Exception { if (entity.getId() != null) { List previousEntityList = this.getEntities(session, entity.getId(), Node.SYS_STATUS_CURRENT_VERSION, entity.getType(), null, false); @@ -635,12 +610,23 @@ Entity previousEntity = previousEntityList.get(0); logger.info("Saving previous entity: " + previousEntity); - this.savePreviousEntity(session, previousEntity); + this.persistEntityAsPrevious(session, previousEntity); } } this.saveCurrentEntity(session, entity, null); } + /** + * Save the entity as (new) current version using the given session. + * + * Sets system_status to CURRENT_VERSION and updates row_id, version, modification_time, + * etc. + * + * @param session + * @param entity + * @param idSequence + * @throws Exception + */ private void saveCurrentEntity(Session session, Entity entity, Sequence idSequence) throws Exception { Long time = System.currentTimeMillis(); @@ -654,12 +640,17 @@ entity.autoNormalize(); // generating of id, connecting rels, atts and views to the entity this.prepareEntity(session, entity, idSequence); - this.saveEntity(session, entity); + this.persistEntity(session, entity); } /** - * Here the modification time will be propagated from the entity to its - * relations an attributes. + * Update the entity to prepare it for persisting. + * + * If the ID is null new IDs will be assigned for the entity and its + * attributes and relations. + * The modification time is propagated from the entity to its + * attributes and relations. + * Own-values are normalized. * * @param session * @param entity @@ -772,42 +763,57 @@ } /** - * Saves an entity setting its system state as previous_version + * Set an entities' system state to PREVIOUS_VERSION and persist it. + * + * Also persists the entities' attributes and relations. * * @param session * @param entity */ - private void savePreviousEntity(Session session, Entity entity) { + private void persistEntityAsPrevious(Session session, Entity entity) { entity.setSystemStatus(Node.SYS_STATUS_PREVIOUS_VERSION); + txLog.debug("* START save previous entity..."); + txLog.info("save previous entity: "+entity.toEncString()); session.save(entity); for (Attribute attribute : entity.getAttributes()) { - logger.debug(" saving prev entity attribute: "+attribute); + txLog.info("save previous entity attribute: "+attribute.toEncString()); session.save(attribute); } for (Relation rel : entity.getSourceRelations()) { + txLog.info("save previous source relation: "+rel.toEncString()); session.save(rel); for (Attribute att : rel.getAttributes()) { - logger.debug(" saving prev (source)relation attribute: "+rel); + txLog.info("save previous source relation attribute: "+att.toEncString()); session.save(att); } } for (Relation rel : entity.getTargetRelations()) { + txLog.info("save previous target relation: "+rel.toEncString()); session.save(rel); for (Attribute att : rel.getAttributes()) { - logger.debug(" saving prev (target)relation attribute: "+rel); + txLog.info("save previous target relation attribute: "+att.toEncString()); session.save(att); } } for (View view : entity.getViews()) { session.save(view); } + txLog.debug("* End ...save previous entity"); } - private void saveEntity(Session session, Entity entity) throws Exception { - logger.info("Saving current entity: " + entity); + /** + * Persist a (current) entity and its attributes and relations. + * + * @param session + * @param entity + * @throws Exception + */ + private void persistEntity(Session session, Entity entity) throws Exception { + txLog.info("* START save entity..."); + txLog.info("save entity: "+entity.toEncString()); session.save(entity); for (Attribute attribute : entity.getAttributes()) { - logger.debug(" saving entity attribute: "+attribute); + txLog.info("save entity attribute: "+attribute.toEncString()); session.save(attribute); } for (Relation rel : entity.getSourceRelations()) { @@ -817,9 +823,10 @@ "Either the sourceId or the targetId was not initialized to the source relation: " + rel.getOwnValue()); } + txLog.info("save source relation: "+rel.toEncString()); session.save(rel); for (Attribute att : rel.getAttributes()) { - logger.debug(" saving (source)relation attribute: "+att); + txLog.info("save source relation attribute: "+att.toEncString()); session.save(att); } } @@ -830,9 +837,10 @@ "Either the sourceId or the targetId was not initialized to the target relation: " + rel.getOwnValue()); } + txLog.info("save target relation: "+rel.toEncString()); session.save(rel); for (Attribute att : rel.getAttributes()) { - logger.debug(" saving (target)relation attribute: "+att); + txLog.info("save target relation attribute: "+att.toEncString()); session.save(att); } } @@ -840,15 +848,15 @@ // Call of ownValue Generator. // TODO: the method should be used always? what would happen if the // ownValue returns null? - if (!isImportModus()) { - String ownValue = this.getOwnValueGenerator().generateOwnValue( - entity, session); + if (!isImportMode()) { + String ownValue = this.getOwnValueGenerator().generateOwnValue(entity, session); if (StringUtils.isNotEmpty(ownValue)) { entity.setOwnValue(ownValue); entity.autoNormalize(); session.save(entity); } } + txLog.debug("* ...END save entity"); } public OwnValueGenerator getOwnValueGenerator() { @@ -861,7 +869,7 @@ /** *

- * Returns entities with their corresponded contain. + * Returns entities with their corresponding contents. *

* * @param session @@ -927,7 +935,7 @@ /** *

- * Returns entities with their corresponded contain. + * Returns entities with their corresponding content. *

* * @param id @@ -1055,7 +1063,10 @@ entity.setSourceRelations(new ArrayList()); entity.setTargetRelations(new ArrayList()); - // FIXME: getNodes finds all attributes if id=null! + /* + * Danger: getNodes finds all attributes in the db and tries to attach them to + * this entity if id=null! + */ if (entity.getId() == null) { logger.error("Entity with id=null! Abort loading attributes."); return entity; @@ -1080,7 +1091,10 @@ } else if (node instanceof Relation) { Relation rel = (Relation) node; // new attr for relations - // FIXME: getNodes finds all attributes if id=null! + /* + * Danger: getNodes finds all attributes in the db and tries to attach them to + * this relation if id=null! + */ if (rel.getId() == null) { logger.error("Relation with id=null! Abort loading attributes."); continue; @@ -1101,8 +1115,7 @@ } else if (node instanceof View) { entity.getViews().add((View) node); } else { - throw new IllegalArgumentException("Invalid node found: " - + node); + throw new IllegalArgumentException("Invalid node found: " + node); } } @@ -1123,7 +1136,10 @@ if (node instanceof Relation) { Relation rel = (Relation) node; // new attr for relations - // FIXME: getNodes finds all attributes if id=null! + /* + * Danger: getNodes finds all attributes in the db and tries to attach them to + * this relation if id=null! + */ if (rel.getId() == null) { logger.error("Relation with id=null! Abort loading attributes."); continue; @@ -1433,12 +1449,12 @@ this.configurationService = configurationService; } - public boolean isImportModus() { - return importModus; + public boolean isImportMode() { + return importMode; } public void setImportModus(boolean importModus) { - this.importModus = importModus; + this.importMode = importModus; } // #################################################################