You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2016/09/28 15:04:48 UTC
[1/2] cayenne git commit: CAY-2113 cdbimport: Reverse-engineering
reinstates previously ignored columns
Repository: cayenne
Updated Branches:
refs/heads/master 43978ffcc -> f7f33b557
CAY-2113 cdbimport: Reverse-engineering reinstates previously ignored columns
* unit test to reproduce
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/d58f7221
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/d58f7221
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/d58f7221
Branch: refs/heads/master
Commit: d58f7221f54fd4ec4b692e8172ebad700df6e66d
Parents: 43978ff
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Wed Sep 28 16:45:56 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Wed Sep 28 17:12:10 2016 +0300
----------------------------------------------------------------------
.../cayenne/tools/DbImporterMojoTest.java | 12 ++++++
.../testPreserveCustomObjMappings-pom.xml | 43 ++++++++++++++++++++
.../testPreserveCustomObjMappings.map.xml | 33 +++++++++++++++
...testPreserveCustomObjMappings.map.xml-result | 35 ++++++++++++++++
.../dbimport/testPreserveCustomObjMappings.sql | 28 +++++++++++++
5 files changed, 151 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d58f7221/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java b/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
index 7f60aa1..1f0ed60 100644
--- a/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
+++ b/plugins/maven-cayenne-plugin/src/test/java/org/apache/cayenne/tools/DbImporterMojoTest.java
@@ -160,6 +160,18 @@ public class DbImporterMojoTest extends AbstractMojoTestCase {
test("testOneToOne");
}
+ /**
+ * Q: what happens if an attribute or relationship is unmapped in the object layer, but then the underlying table
+ * changes.
+ * A: it should not recreate unmapped attributes/relationships. Only add an attribute for the new column.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testPreserveCustomObjMappings() throws Exception {
+ test("testPreserveCustomObjMappings");
+ }
+
/**
* Q: what happens if a relationship existed over a column that was later deleted? and \u2018skipRelLoading\u2019 is true
* A: it should remove relationship and column
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d58f7221/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings-pom.xml
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings-pom.xml b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings-pom.xml
new file mode 100644
index 0000000..1dc63ea
--- /dev/null
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings-pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <name>DbImporterMojo Test1</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-cayenne-plugin</artifactId>
+ <configuration>
+ <map>target/test-classes/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml</map>
+ <driver>org.apache.derby.jdbc.EmbeddedDriver</driver>
+ <url>jdbc:derby:memory:DbImporterMojoTest;create=true</url>
+
+ <schema>
+ <name>SCHEMA_01</name>
+ </schema>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d58f7221/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml
new file mode 100644
index 0000000..93f6b27
--- /dev/null
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<data-map xmlns="http://cayenne.apache.org/schema/8/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/8/modelMap http://cayenne.apache.org/schema/8/modelMap.xsd"
+ project-version="8">
+ <property name="defaultSchema" value="SCHEMA_01"/>
+ <db-entity name="PARENT" schema="SCHEMA_01">
+ <db-attribute name="COL2" type="CHAR" length="25"/>
+ <db-attribute name="COL3" type="DECIMAL" length="10" scale="2"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ </db-entity>
+ <obj-entity name="Parent" className="Parent" dbEntityName="PARENT">
+ <obj-attribute name="col2" type="java.lang.String" db-attribute-path="COL2"/>
+ </obj-entity>
+</data-map>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d58f7221/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml-result
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml-result b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml-result
new file mode 100644
index 0000000..7c8036d
--- /dev/null
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.map.xml-result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<data-map xmlns="http://cayenne.apache.org/schema/8/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/8/modelMap http://cayenne.apache.org/schema/8/modelMap.xsd"
+ project-version="8">
+ <property name="defaultSchema" value="SCHEMA_01"/>
+ <db-entity name="PARENT" schema="SCHEMA_01">
+ <db-attribute name="COL2" type="CHAR" length="25"/>
+ <db-attribute name="COL3" type="DECIMAL" length="10" scale="2"/>
+ <db-attribute name="COL4" type="VARCHAR" length="25"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true" length="10"/>
+ </db-entity>
+ <obj-entity name="Parent" className="Parent" dbEntityName="PARENT">
+ <obj-attribute name="col2" type="java.lang.String" db-attribute-path="COL2"/>
+ <obj-attribute name="col4" type="java.lang.String" db-attribute-path="COL4"/>
+ </obj-entity>
+</data-map>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/d58f7221/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.sql
----------------------------------------------------------------------
diff --git a/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.sql b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.sql
new file mode 100644
index 0000000..32be3a5
--- /dev/null
+++ b/plugins/maven-cayenne-plugin/src/test/resources/org/apache/cayenne/tools/dbimport/testPreserveCustomObjMappings.sql
@@ -0,0 +1,28 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+CREATE SCHEMA schema_01;
+SET SCHEMA schema_01;
+
+CREATE TABLE schema_01.Parent (
+ id INTEGER NOT NULL,
+ COL2 CHAR(25),
+ COL3 DECIMAL(10,2),
+ COL4 VARCHAR(25),
+
+ PRIMARY KEY (id)
+ );
\ No newline at end of file
[2/2] cayenne git commit: CAY-2113 cdbimport: Reverse-engineering
reinstates previously ignored columns
Posted by aa...@apache.org.
CAY-2113 cdbimport: Reverse-engineering reinstates previously ignored columns
* fixing...
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/f7f33b55
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/f7f33b55
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/f7f33b55
Branch: refs/heads/master
Commit: f7f33b5570dc704d88322e2ac08bda677050a174
Parents: d58f722
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Wed Sep 28 16:45:56 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Wed Sep 28 18:02:35 2016 +0300
----------------------------------------------------------------------
.../cayenne/merge/AbstractToModelToken.java | 7 -
.../apache/cayenne/merge/AddColumnToModel.java | 10 +-
.../cayenne/merge/AddRelationshipToModel.java | 14 +-
.../cayenne/merge/CreateTableToModel.java | 10 +-
.../apache/cayenne/util/EntityMergeSupport.java | 277 +++++++++++--------
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
6 files changed, 186 insertions(+), 133 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/cayenne-server/src/main/java/org/apache/cayenne/merge/AbstractToModelToken.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/AbstractToModelToken.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/AbstractToModelToken.java
index e2ca05f..49b680b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/merge/AbstractToModelToken.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/AbstractToModelToken.java
@@ -23,7 +23,6 @@ import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.util.EntityMergeSupport;
/**
* Common abstract superclass for all {@link MergerToken}s going from the database to the
@@ -47,12 +46,6 @@ public abstract class AbstractToModelToken implements MergerToken {
return MergeDirection.TO_MODEL;
}
- protected void synchronizeWithObjEntity(DbEntity entity) {
- for (ObjEntity objEntity : entity.mappedObjEntities()) {
- new EntityMergeSupport(objEntity.getDataMap()).synchronizeWithDbEntity(objEntity);
- }
- }
-
protected static void remove(ModelMergeDelegate mergerContext, DbRelationship rel, boolean reverse) {
if (rel == null) {
return;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/cayenne-server/src/main/java/org/apache/cayenne/merge/AddColumnToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/AddColumnToModel.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/AddColumnToModel.java
index 283241c..9e96928 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/merge/AddColumnToModel.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/AddColumnToModel.java
@@ -40,7 +40,15 @@ public class AddColumnToModel extends AbstractToModelToken.EntityAndColumn {
public void execute(MergerContext mergerContext) {
getEntity().addAttribute(getColumn());
- synchronizeWithObjEntity(getEntity());
+
+ // TODO: use EntityMergeSupport from DbImportConfiguration... otherwise we are ignoring a bunch of
+ // important settings
+
+ EntityMergeSupport entityMergeSupport = new EntityMergeSupport(mergerContext.getDataMap());
+ for(ObjEntity e : getEntity().mappedObjEntities()) {
+ entityMergeSupport.synchronizeOnDbAttributeAdded(e, getColumn());
+ }
+
mergerContext.getModelMergeDelegate().dbAttributeAdded(getColumn());
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/cayenne-server/src/main/java/org/apache/cayenne/merge/AddRelationshipToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/AddRelationshipToModel.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/AddRelationshipToModel.java
index 5e05b52..42d7329 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/merge/AddRelationshipToModel.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/AddRelationshipToModel.java
@@ -21,8 +21,8 @@ package org.apache.cayenne.merge;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
-
-import static org.apache.cayenne.util.Util.join;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.util.EntityMergeSupport;
public class AddRelationshipToModel extends AbstractToModelToken.Entity {
@@ -42,7 +42,15 @@ public class AddRelationshipToModel extends AbstractToModelToken.Entity {
public void execute(MergerContext mergerContext) {
getEntity().addRelationship(rel);
// TODO: add reverse relationship as well if it does not exist
- synchronizeWithObjEntity(getEntity());
+
+ // TODO: use EntityMergeSupport from DbImportConfiguration... otherwise we are ignoring a bunch of
+ // important settings
+
+ EntityMergeSupport entityMergeSupport = new EntityMergeSupport(mergerContext.getDataMap());
+ for(ObjEntity e : getEntity().mappedObjEntities()) {
+ entityMergeSupport.synchronizeOnDbRelationshipAdded(e, rel);
+ }
+
mergerContext.getModelMergeDelegate().dbRelationshipAdded(rel);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java b/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java
index 61a266a..cdd6009 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/merge/CreateTableToModel.java
@@ -22,7 +22,7 @@ import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.naming.NameConverter;
-import org.apache.cayenne.util.Util;
+import org.apache.cayenne.util.EntityMergeSupport;
/**
* A {@link MergerToken} to add a {@link DbEntity} to a {@link DataMap}
@@ -85,8 +85,12 @@ public class CreateTableToModel extends AbstractToModelToken.Entity {
map.addObjEntity(objEntity);
- synchronizeWithObjEntity(getEntity());
-
+ // presumably there are no other ObjEntities pointing to this DbEntity, so syncing just this one...
+
+ // TODO: use EntityMergeSupport from DbImportConfiguration... otherwise we are ignoring a bunch of
+ // important settings
+ new EntityMergeSupport(map).synchronizeWithDbEntity(objEntity);
+
mergerContext.getModelMergeDelegate().dbEntityAdded(getEntity());
mergerContext.getModelMergeDelegate().objEntityAdded(objEntity);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
index 5bcccce..7c12600 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/EntityMergeSupport.java
@@ -19,13 +19,6 @@
package org.apache.cayenne.util;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbAttribute;
@@ -36,13 +29,20 @@ import org.apache.cayenne.map.Entity;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.map.naming.LegacyNameGenerator;
import org.apache.cayenne.map.naming.DefaultUniqueNameGenerator;
+import org.apache.cayenne.map.naming.LegacyNameGenerator;
import org.apache.cayenne.map.naming.NameCheckers;
import org.apache.cayenne.map.naming.ObjectNameGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* Implements methods for entity merging.
*/
@@ -64,20 +64,17 @@ public class EntityMergeSupport {
}
private final DataMap map;
-
- protected boolean removeMeaningfulFKs;
- protected boolean removeMeaningfulPKs;
- protected boolean usePrimitives;
-
/**
* Strategy for choosing names for entities, attributes and relationships
*/
private final ObjectNameGenerator nameGenerator;
-
/**
* Listeners of merge process.
*/
private final List<EntityMergeListener> listeners = new ArrayList<EntityMergeListener>();
+ protected boolean removeMeaningfulFKs;
+ protected boolean removeMeaningfulPKs;
+ protected boolean usePrimitives;
public EntityMergeSupport(DataMap map) {
this(map, new LegacyNameGenerator(), true);
@@ -102,7 +99,7 @@ public class EntityMergeSupport {
/**
* Updates each one of the collection of ObjEntities, adding attributes and
* relationships based on the current state of its DbEntity.
- *
+ *
* @return true if any ObjEntity has changed as a result of synchronization.
* @since 1.2 changed signature to use Collection instead of List.
*/
@@ -134,7 +131,7 @@ public class EntityMergeSupport {
/**
* Updates ObjEntity attributes and relationships based on the current state
* of its DbEntity.
- *
+ *
* @return true if the ObjEntity has changed as a result of synchronization.
*/
public boolean synchronizeWithDbEntity(ObjEntity entity) {
@@ -165,6 +162,32 @@ public class EntityMergeSupport {
return changed;
}
+ /**
+ * @since 4.0
+ */
+ public boolean synchronizeOnDbAttributeAdded(ObjEntity entity, DbAttribute dbAttribute) {
+
+ Collection<DbRelationship> incomingRels = getIncomingRelationships(dbAttribute.getEntity());
+ if (isMissingFromObjEntity(entity, dbAttribute, incomingRels)) {
+ addMissingAttribute(entity, dbAttribute);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @since 4.0
+ */
+ public boolean synchronizeOnDbRelationshipAdded(ObjEntity entity, DbRelationship dbRelationship) {
+
+ if (isMissingFromObjEntity(entity, dbRelationship)) {
+ addMissingRelationship(entity, dbRelationship);
+ }
+
+ return true;
+ }
+
private boolean addMissingRelationships(ObjEntity entity) {
List<DbRelationship> relationshipsToAdd = getRelationshipsToAdd(entity);
if (relationshipsToAdd.isEmpty()) {
@@ -172,26 +195,9 @@ public class EntityMergeSupport {
}
for (DbRelationship dr : relationshipsToAdd) {
- DbEntity targetEntity = dr.getTargetEntity();
-
- Collection<ObjEntity> mappedObjEntities = map.getMappedEntities(targetEntity);
- if (!mappedObjEntities.isEmpty()) {
- for (Entity mappedTarget : mappedObjEntities) {
- createObjRelationship(entity, dr, mappedTarget.getName());
- }
- } else {
- if (targetEntity == null) {
- targetEntity = new DbEntity(dr.getTargetEntityName());
- }
- if (dr.getTargetEntityName() != null) {
- boolean needGeneratedEntity = createObjRelationship(entity, dr, nameGenerator.createObjEntityName(targetEntity));
- if (needGeneratedEntity) {
- LOG.warn("Can't find ObjEntity for " + dr.getTargetEntityName());
- LOG.warn("Db Relationship (" + dr + ") will have GUESSED Obj Relationship reflection. ");
- }
- }
- }
+ addMissingRelationship(entity, dr);
}
+
return true;
}
@@ -237,26 +243,55 @@ public class EntityMergeSupport {
private boolean addMissingAttributes(ObjEntity entity) {
boolean changed = false;
+
for (DbAttribute da : getAttributesToAdd(entity)) {
+ addMissingAttribute(entity, da);
+ changed = true;
+ }
+ return changed;
+ }
- String attrName = DefaultUniqueNameGenerator.generate(NameCheckers.objAttribute, entity,
- nameGenerator.createObjAttributeName(da));
+ private void addMissingRelationship(ObjEntity entity, DbRelationship dbRelationship) {
+ DbEntity targetEntity = dbRelationship.getTargetEntity();
+
+ Collection<ObjEntity> mappedObjEntities = map.getMappedEntities(targetEntity);
+ if (!mappedObjEntities.isEmpty()) {
+ for (Entity mappedTarget : mappedObjEntities) {
+ createObjRelationship(entity, dbRelationship, mappedTarget.getName());
+ }
+ } else {
- String type = TypesMapping.getJavaBySqlType(da.getType());
- if (usePrimitives) {
- String primitive = CLASS_TO_PRIMITIVE.get(type);
- if (primitive != null) {
- type = primitive;
+ if (targetEntity == null) {
+ targetEntity = new DbEntity(dbRelationship.getTargetEntityName());
+ }
+
+ if (dbRelationship.getTargetEntityName() != null) {
+ boolean needGeneratedEntity = createObjRelationship(entity, dbRelationship,
+ nameGenerator.createObjEntityName(targetEntity));
+ if (needGeneratedEntity) {
+ LOG.warn("Can't find ObjEntity for " + dbRelationship.getTargetEntityName());
+ LOG.warn("Db Relationship (" + dbRelationship + ") will have GUESSED Obj Relationship reflection. ");
}
}
+ }
+ }
- ObjAttribute oa = new ObjAttribute(attrName, type, entity);
- oa.setDbAttributePath(da.getName());
- entity.addAttribute(oa);
- fireAttributeAdded(oa);
- changed = true;
+ private void addMissingAttribute(ObjEntity entity, DbAttribute da) {
+ String attrName = DefaultUniqueNameGenerator.generate(NameCheckers.objAttribute, entity,
+ nameGenerator.createObjAttributeName(da));
+
+ String type = TypesMapping.getJavaBySqlType(da.getType());
+ if (usePrimitives) {
+ String primitive = CLASS_TO_PRIMITIVE.get(type);
+ if (primitive != null) {
+ type = primitive;
+ }
}
- return changed;
+
+ ObjAttribute oa = new ObjAttribute(attrName, type, entity);
+ oa.setDbAttributePath(da.getName());
+ entity.addAttribute(oa);
+ fireAttributeAdded(oa);
}
private boolean getRidOfAttributesThatAreNowSrcAttributesForRelationships(ObjEntity entity) {
@@ -275,7 +310,7 @@ public class EntityMergeSupport {
/**
* Returns a list of DbAttributes that are mapped to foreign keys.
- *
+ *
* @since 1.2
*/
public Collection<DbAttribute> getMeaningfulFKs(ObjEntity objEntity) {
@@ -301,102 +336,106 @@ public class EntityMergeSupport {
DbEntity dbEntity = objEntity.getDbEntity();
List<DbAttribute> missing = new ArrayList<DbAttribute>();
-
- Collection<DbRelationship> rels = dbEntity.getRelationships();
Collection<DbRelationship> incomingRels = getIncomingRelationships(dbEntity);
for (DbAttribute dba : dbEntity.getAttributes()) {
- if (dba.getName() == null || objEntity.getAttributeForDbAttribute(dba) != null) {
- continue;
+ if (isMissingFromObjEntity(objEntity, dba, incomingRels)) {
+ missing.add(dba);
}
+ }
- boolean removeMeaningfulPKs = removePK(dbEntity);
- if (removeMeaningfulPKs && dba.isPrimaryKey()) {
- continue;
- }
+ return missing;
+ }
- // check FK's
- boolean isFK = false;
- Iterator<DbRelationship> rit = rels.iterator();
- while (!isFK && rit.hasNext()) {
- DbRelationship rel = rit.next();
- for (DbJoin join : rel.getJoins()) {
- if (join.getSource() == dba) {
- isFK = true;
- break;
- }
- }
- }
+ protected boolean isMissingFromObjEntity(ObjEntity entity, DbAttribute dbAttribute, Collection<DbRelationship> incomingRels) {
- if (!removeMeaningfulPKs) {
- if (!dba.isPrimaryKey() && isFK) {
- continue;
- }
- } else {
- if (isFK) {
- continue;
+ if (dbAttribute.getName() == null || entity.getAttributeForDbAttribute(dbAttribute) != null) {
+ return false;
+ }
+
+ boolean removeMeaningfulPKs = removePK(dbAttribute.getEntity());
+ if (removeMeaningfulPKs && dbAttribute.isPrimaryKey()) {
+ return false;
+ }
+
+ // check FK's
+ boolean isFK = false;
+ Iterator<DbRelationship> rit = dbAttribute.getEntity().getRelationships().iterator();
+ while (!isFK && rit.hasNext()) {
+ DbRelationship rel = rit.next();
+ for (DbJoin join : rel.getJoins()) {
+ if (join.getSource() == dbAttribute) {
+ isFK = true;
+ break;
}
}
+ }
- // check incoming relationships
- rit = incomingRels.iterator();
- while (!isFK && rit.hasNext()) {
- DbRelationship rel = rit.next();
- for (DbJoin join : rel.getJoins()) {
- if (join.getTarget() == dba) {
- isFK = true;
- break;
- }
- }
+ if (!removeMeaningfulPKs) {
+ if (!dbAttribute.isPrimaryKey() && isFK) {
+ return false;
}
+ } else {
+ if (isFK) {
+ return false;
+ }
+ }
- if (!removeMeaningfulPKs) {
- if (!dba.isPrimaryKey() && isFK) {
- continue;
- }
- } else {
- if (isFK) {
- continue;
+ // check incoming relationships
+ rit = incomingRels.iterator();
+ while (!isFK && rit.hasNext()) {
+ DbRelationship rel = rit.next();
+ for (DbJoin join : rel.getJoins()) {
+ if (join.getTarget() == dbAttribute) {
+ isFK = true;
+ break;
}
}
+ }
- missing.add(dba);
+ if (!removeMeaningfulPKs) {
+ if (!dbAttribute.isPrimaryKey() && isFK) {
+ return false;
+ }
+ } else {
+ if (isFK) {
+ return false;
+ }
}
- return missing;
+ return true;
}
- private Collection<DbRelationship> getIncomingRelationships(DbEntity entity) {
- Collection<DbRelationship> incoming = new ArrayList<DbRelationship>();
+ protected boolean isMissingFromObjEntity(ObjEntity entity, DbRelationship dbRelationship) {
+ return dbRelationship.getName() != null && entity.getRelationshipForDbRelationship(dbRelationship) == null;
+ }
- for (DbEntity nextEntity : entity.getDataMap().getDbEntities()) {
- for (DbRelationship relationship : nextEntity.getRelationships()) {
+ private Collection<DbRelationship> getIncomingRelationships(DbEntity entity) {
+ Collection<DbRelationship> incoming = new ArrayList<DbRelationship>();
- // TODO: PERFORMANCE 'getTargetEntity' is generally slow, called
- // in this iterator it is showing (e.g. in YourKit profiles)..
- // perhaps use cheaper 'getTargetEntityName()' or even better -
- // pre-cache all relationships by target entity to avoid O(n)
- // search ?
- // (need to profile to prove the difference)
- if (entity == relationship.getTargetEntity()) {
- incoming.add(relationship);
- }
- }
- }
+ for (DbEntity nextEntity : entity.getDataMap().getDbEntities()) {
+ for (DbRelationship relationship : nextEntity.getRelationships()) {
- return incoming;
- }
+ // TODO: PERFORMANCE 'getTargetEntity' is generally slow, called
+ // in this iterator it is showing (e.g. in YourKit profiles)..
+ // perhaps use cheaper 'getTargetEntityName()' or even better -
+ // pre-cache all relationships by target entity to avoid O(n)
+ // search ?
+ // (need to profile to prove the difference)
+ if (entity == relationship.getTargetEntity()) {
+ incoming.add(relationship);
+ }
+ }
+ }
+
+ return incoming;
+ }
protected List<DbRelationship> getRelationshipsToAdd(ObjEntity objEntity) {
List<DbRelationship> missing = new ArrayList<DbRelationship>();
for (DbRelationship dbRel : objEntity.getDbEntity().getRelationships()) {
- // check if adding it makes sense at all
- if (dbRel.getName() == null) {
- continue;
- }
-
- if (objEntity.getRelationshipForDbRelationship(dbRel) == null) {
+ if (isMissingFromObjEntity(objEntity, dbRel)) {
missing.add(dbRel);
}
}
@@ -472,8 +511,8 @@ public class EntityMergeSupport {
}
/**
- * @since 4.0
* @param usePrimitives
+ * @since 4.0
*/
public void setUsePrimitives(boolean usePrimitives) {
this.usePrimitives = usePrimitives;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/f7f33b55/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index d6af992..aa04b5f 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -31,6 +31,7 @@ CAY-2106 cayenne-crypto: allow DI contribution of type converters inside ValueTr
CAY-2107 cayenne-crypto: Lazy initialization of crypto subsystem
CAY-2111 Unbind transaction object from the current thread for iterated queries
CAY-2112 Expose callback for "performInTransaction"
+CAY-2113 cdbimport: Reverse-engineering reinstates previously ignored columns
Bug Fixes: