Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class EntityRowReader implements RowReader<DataRow> {
this.entityName = classDescriptor.getEntity().getName();
}

int segmentWidth = segmentMetadata.getFields().size();
int segmentWidth = segmentMetadata.getColumnCount();
this.startIndex = segmentMetadata.getColumnOffset();
this.converters = new ExtendedType[segmentWidth];
this.types = new int[segmentWidth];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,10 @@ public boolean visitToOne(ToOneProperty property) {

int count = result.getDbAttributes().size();
for(int i=0; i<count; i++) {
processTranslationResult(result, i);
addEntityResultField(result.getDbAttributes().get(i));
ResultNodeDescriptor resultNodeDescriptor = processTranslationResult(result, i);
if(resultNodeDescriptor != null) {
addEntityResultField(result.getDbAttributes().get(i));
}
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,8 @@ public boolean visitToOne(ToOneProperty property) {

// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {

if (visited.add(column.getName())) {
String dbAttributePath = column.getDbAttributePath().value();
String dbAttributePath = column.getDbAttributePath().value();
if (visited.add(dbAttributePath)) {
compiledResult.addDbField(
"fetch." + prefix + "." + dbAttributePath,
prefix + "." + dbAttributePath);
Expand Down Expand Up @@ -363,8 +362,9 @@ public boolean visitToOne(ToOneProperty property) {

// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
if (visited.add(column.getName())) {
entityResult.addDbField(column.getDbAttributePath().value(), prefix + index[0]++);
String dbAttributePath = column.getDbAttributePath().value();
if (visited.add(dbAttributePath)) {
entityResult.addDbField(dbAttributePath, prefix + index[0]++);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,19 @@ public class DefaultEntityResultSegment implements EntityResultSegment {
private ClassDescriptor classDescriptor;
private Map<String, String> fields;
private int offset;
private int columnCount;

public DefaultEntityResultSegment(ClassDescriptor classDescriptor,
Map<String, String> fields, int offset) {
this(classDescriptor, fields, offset, fields != null ? fields.size() : 0);
}

public DefaultEntityResultSegment(ClassDescriptor classDescriptor,
Map<String, String> fields, int offset, int columnCount) {
this.classDescriptor = classDescriptor;
this.fields = fields;
this.offset = offset;
this.columnCount = columnCount;
}

public ClassDescriptor getClassDescriptor() {
Expand All @@ -47,6 +54,11 @@ public Map<String, String> getFields() {
return fields;
}

@Override
public int getColumnCount() {
return columnCount;
}

public int getColumnOffset() {
return offset;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ public Map<String, String> getDbFields(EntityResolver resolver) {
return dbFields;
}

/**
* Returns the total number of fields added to this result.
*/
public int getFieldCount() {
return fields != null ? fields.size() : 0;
}

private ObjEntity getRootEntity(EntityResolver resolver) {
if (entityName != null) {
return resolver.getObjEntity(entityName);
Expand Down
5 changes: 3 additions & 2 deletions cayenne/src/main/java/org/apache/cayenne/map/SQLResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ public List<Object> getResolvedComponents(EntityResolver resolver) {
} else if (component instanceof EntityResult) {
EntityResult entityResult = (EntityResult) component;
Map<String, String> fields = entityResult.getDbFields(resolver);
int columnCount = entityResult.getFieldCount();

String entityName = entityResult.getEntityName();
if (entityName == null) {
entityName = resolver.getObjEntity(entityResult.getEntityClass()).getName();
}

ClassDescriptor classDescriptor = resolver.getClassDescriptor(entityName);
resolvedComponents.add(new DefaultEntityResultSegment(classDescriptor, fields, offset));
offset = offset + fields.size();
resolvedComponents.add(new DefaultEntityResultSegment(classDescriptor, fields, offset, columnCount));
offset = offset + columnCount;
} else if (component instanceof EmbeddedResult) {
EmbeddedResult embeddedResult = (EmbeddedResult)component;
Map<String, String> fields = embeddedResult.getFields();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public interface EntityResultSegment {
*/
Map<String, String> getFields();

/**
* Returns the total number of columns in this segment.
*/
int getColumnCount();

/**
* Performs a reverse lookup of the column path for a given ResultSet label.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public String getColumnPath(String resultSetLabel) {
return reverseFields.get(resultSetLabel);
}

@Override
public int getColumnCount() {
return fields.size();
}

void addObjectField(String attributeName, String column) {
ObjEntity entity = classDescriptor.getEntity();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.ColumnSelect;
import org.apache.cayenne.query.EJBQLQuery;
import org.apache.cayenne.query.ObjectSelect;
Expand Down Expand Up @@ -727,6 +728,55 @@ public void testUpdateFlattenedRelationshipWithInverse() throws SQLException {
}
}

@Test
public void testColumnQueryVerticallyInheritedToVerticallyInherited() throws SQLException {
TableHelper ivDocumentTable = new TableHelper(dbHelper, "IV_DOCUMENT");
ivDocumentTable.setColumns("ID", "TYPE").setColumnTypes(Types.INTEGER, Types.CHAR);

TableHelper ivDocumentLineTable = new TableHelper(dbHelper, "IV_DOCUMENT_LINE");
ivDocumentLineTable.setColumns("ID", "TYPE", "DOCUMENT_ID").setColumnTypes(Types.INTEGER, Types.CHAR, Types.INTEGER);

TableHelper IvDocumentATable = new TableHelper(dbHelper, "IV_DOCUMENT_A");
IvDocumentATable.setColumns("ID").setColumnTypes(Types.INTEGER);

TableHelper IvDocumentALineTable = new TableHelper(dbHelper, "IV_DOCUMENT_A_LINE");
IvDocumentALineTable.setColumns("ID").setColumnTypes(Types.INTEGER);

TableHelper IvDocumentBTable = new TableHelper(dbHelper, "IV_DOCUMENT_B");
IvDocumentBTable.setColumns("ID", "RELATED_A_ID").setColumnTypes(Types.INTEGER, Types.INTEGER);

TableHelper IvDocumentBLineTable = new TableHelper(dbHelper, "IV_DOCUMENT_B_LINE");
IvDocumentBLineTable.setColumns("ID").setColumnTypes(Types.INTEGER);

int documentAId = 1;
ivDocumentTable.insert(documentAId, "A");
IvDocumentATable.insert(documentAId);

int documentALineId = 2;
ivDocumentLineTable.insert(documentALineId, "A", documentAId);
IvDocumentALineTable.insert(documentALineId);

int documentBId = 3;
ivDocumentTable.insert(documentBId, "B");
IvDocumentBTable.insert(documentBId, documentAId);

int documentBLineId = 4;
ivDocumentLineTable.insert(documentBLineId, "B", documentBId);
IvDocumentBLineTable.insert(documentBLineId);

{
ObjectContext newContext = runtime.newContext();

IvDocument documentA = ObjectSelect.query(IvDocumentALine.class).where(ExpressionFactory.matchDbIdExp("ID", documentALineId)).column(IvDocumentALine.DOCUMENT).selectOne(newContext);
assertNotNull(documentA);
assertEquals(IvDocumentA.class, documentA.getClass());

IvDocument documentB = ObjectSelect.query(IvDocumentBLine.class).where(ExpressionFactory.matchDbIdExp("ID", documentBLineId)).column(IvDocumentBLine.DOCUMENT).selectOne(newContext);
assertNotNull(documentB);
assertEquals(IvDocumentB.class, documentB.getClass());
}
}

@Test
public void testDeleteFlattenedNoValues() throws SQLException {
ivAbstractTable.insert(1, null, "S");
Expand Down Expand Up @@ -1188,6 +1238,7 @@ public void testColumnSelectVerticalInheritance_Sub1() throws SQLException {
}

@Test
// @Ignore("Address CAY-2911")
public void testColumnSelectVerticalInheritance_Sub1Sub1() throws SQLException {
TableHelper ivRootTable = new TableHelper(dbHelper, "IV_ROOT");
ivRootTable.setColumns("ID", "NAME", "DISCRIMINATOR");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocument;

public abstract class IvDocument extends _IvDocument {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocumentA;

public class IvDocumentA extends _IvDocumentA {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocumentALine;

public class IvDocumentALine extends _IvDocumentALine {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocumentB;

public class IvDocumentB extends _IvDocumentB {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocumentBLine;

public class IvDocumentBLine extends _IvDocumentBLine {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.apache.cayenne.testdo.inheritance_vertical;


import org.apache.cayenne.testdo.inheritance_vertical.auto._IvDocumentLine;

public abstract class IvDocumentLine extends _IvDocumentLine {

private static final long serialVersionUID = 1L;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.apache.cayenne.testdo.inheritance_vertical.auto;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

import org.apache.cayenne.PersistentObject;
import org.apache.cayenne.exp.property.ListProperty;
import org.apache.cayenne.exp.property.NumericIdProperty;
import org.apache.cayenne.exp.property.PropertyFactory;
import org.apache.cayenne.exp.property.SelfProperty;
import org.apache.cayenne.exp.property.StringProperty;
import org.apache.cayenne.testdo.inheritance_vertical.IvDocument;
import org.apache.cayenne.testdo.inheritance_vertical.IvDocumentLine;

/**
* Class _IvDocument was generated by Cayenne.
* It is probably a good idea to avoid changing this class manually,
* since it may be overwritten next time code is regenerated.
* If you need to make any customizations, please use subclass.
*/
public abstract class _IvDocument extends PersistentObject {

private static final long serialVersionUID = 1L;

public static final SelfProperty<IvDocument> SELF = PropertyFactory.createSelf(IvDocument.class);

public static final NumericIdProperty<Integer> ID_PK_PROPERTY = PropertyFactory.createNumericId("ID", "IvDocument", Integer.class);
public static final String ID_PK_COLUMN = "ID";

public static final StringProperty<String> TYPE = PropertyFactory.createString("type", String.class);
public static final ListProperty<IvDocumentLine> LINES = PropertyFactory.createList("lines", IvDocumentLine.class);

protected String type;

protected Object lines;

public void setType(String type) {
beforePropertyWrite("type", this.type, type);
this.type = type;
}

public String getType() {
beforePropertyRead("type");
return this.type;
}

public void addToLines(IvDocumentLine obj) {
addToManyTarget("lines", obj, true);
}

public void removeFromLines(IvDocumentLine obj) {
removeToManyTarget("lines", obj, true);
}

@SuppressWarnings("unchecked")
public List<IvDocumentLine> getLines() {
return (List<IvDocumentLine>)readProperty("lines");
}

@Override
public Object readPropertyDirectly(String propName) {
if(propName == null) {
throw new IllegalArgumentException();
}

switch(propName) {
case "type":
return this.type;
case "lines":
return this.lines;
default:
return super.readPropertyDirectly(propName);
}
}

@Override
public void writePropertyDirectly(String propName, Object val) {
if(propName == null) {
throw new IllegalArgumentException();
}

switch (propName) {
case "type":
this.type = (String)val;
break;
case "lines":
this.lines = val;
break;
default:
super.writePropertyDirectly(propName, val);
}
}

private void writeObject(ObjectOutputStream out) throws IOException {
writeSerialized(out);
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
readSerialized(in);
}

@Override
protected void writeState(ObjectOutputStream out) throws IOException {
super.writeState(out);
out.writeObject(this.type);
out.writeObject(this.lines);
}

@Override
protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
super.readState(in);
this.type = (String)in.readObject();
this.lines = in.readObject();
}

}
Loading