Learn how to add join relationships to an Ad Hoc report and data service in order to export columns from an entire data model in Pull Reports™.
This tutorial expands on the Pull Reports™ catalog configuration concepts
introduced in Tutorial 1 by
enlarging the report data model with <relationship>
configuration.
Relationships join additional database tables to the report's base table in an
infinitely deep join tree.
Relationships in Pull Reports™ are of three types:
to many, <join_column>
to one, <join_column>
to many, <join_table>
Each type is a directional inner or left outer relational join from the relationship parent table to the relationship child table. The three types are differentiated by the cardinality of the relationship, one or many, and whether the foreign key column(s) are present on the relationship tables or on a many-to-many join table.
This tutorial contains an example of each type of relationship plus an advanced example in which a child table joins to an ancestor table. The tutorial gives example configuration as Pull Reports™ XML Catalog files but also includes a comprehensive example in the Catalog Configuration Java API.
For additional relationship configuration examples, see the <relationship>
documentation.
The catalog configuration from Tutorial 1
allows a user to query and export the columns of the base, student
table. To expand our example data model, will add
a table called assignment
containing
student assignments records. The assignment
table
has an assignment.student_id
column which is a foreign key to student.id
.
In this way, one student
record may join
to many assignment
records and the relationship is "to-many"
from student
to assignment
.
Here is the new UML with the additional assignment
table:
You may wonder why the student
to assignment
relationship is described as "to-many" instead of the more common "one-to-many".
This is because Pull Reports™ relational joins are always uni-directional from parent
to child within the report join tree, so the parent cardinality is unimportant.
To add the assignment
table to our report data model, add
a child <relationship>
element to the base table which itself
contains the child, assignment
<table>
. Because
this is a to-many relationship in which the foreign key column is on the child
table, a <join_column>
element specifies the foreign key column,
assignment.student_id
, and referenced
column, student.id
, which participate in the join.
When defining the relationship, we choose not to specify the <relationship>
cardinality
and join
attributes but accept their default values
of many
and left
respectively. The cardinality of
many
is appropriate because the relationship is to-many from student
to assignment
. The join value of left
ensures that
all rows from the student
table will be included in the Export Report REST API export result regardless of whether
a student
row has any referencing assignment
records.
Here is our new Pull Reports™ XML Catalog file which includes the assignment
relationship table:
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://www.pullreports.com/catalog-1.7.0" id="class" name="Class Reports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.pullreports.com/catalog-1.7.0 https://www.pullreports.com/docs/xsd/pullreports-catalog-1.7.0.xsd"> <report id="student-information" name="Student Information"> <export_config defaultColumns='firstn,lastn'/> <table id="student" name="class_info.student" displayName="Student" primaryKeyColumns="id"> <column id="id" name="id" displayName="Student ID" paramType="java.lang.Integer" export="false"/> <column id="firstn" name="first_name" displayName="First Name"/> <column id="lastn" name="last_name" displayName="Last Name"/> <column id="height_in" name="height_inches" displayName="Height (in)" paramType="java.lang.Double"/> <column id="bdate" name="birth_date" displayName="Birth Date" paramType="java.sql.Date"/> <column id="active" name="is_active" displayName="Active?" paramType="java.lang.Boolean" export="false"/> <pre_filter>@active=true</pre_filter> <relationship> <join_column columnName="student_id" referencedColumnName="id" /> <table id="assignment" displayName="Assignment" name="class_info.assignment"> <column id="id" name="id" displayName="Assignment ID" paramType="java.lang.Integer"/> <column id="grade" name="grade" displayName="Grade"/> <column id="name" name="name" displayName="Name"/> </table> </relationship> </table> </report> </catalog>
When adding the assignment
table relationship, note we also specified
the base <table>
's primaryKeyColumns
attribute. This attribute is required
for each table with at least one descendant relationship table of cardinality many
in order to activate the jsontree
and
htmltree
export formats.
Now that the assignment
table is part of the report join tree,
we can include the columns of the assignment
table into the Export Report REST API
export result by adding the /student/assignment
table resource path
to the columns
parameter like so:
/[context]/pullreports/catalog/class/report/student-information/export?columns=/student/assignment
When we added the assignment
table to the report data model, you might have
noticed the assignment.class_id
column.
This column represents a to-one relationship from assignment
to the referenced
class
in which the assignment was given (e.g.
"Algebra II", "An introduction to Computer Science", or "Cities in History").
Here is the new UML which includes the class
table:
To add the class
table to our report data model, add
a child <relationship>
element to the assignment
table which
includes the child, class
table. Because
this is a to-one relationship (e.g. cardinality="one"
) in which the foreign
key column is on the parent
table, a <join_column>
element specifies the foreign key column, assignment.class_id
and referenced column, class.id
, which participate in the join.
Unlike the assignment
table relationship, the class
table
relationship is defined as join="inner"
. A relational inner join is typically desired if
the data model requires the assignment.class_id
column to be not null such that
each assignment
always has one class
. If the
assignment.class_id
column were nullable, a left join
would be typically appropriate because a left join between assignment
and class
would export assignments without a referenced class if the
class
table columns were included in the Export Report REST API export result.
Here is our new Pull Reports™ XML Catalog file which includes the class
relationship table:
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://www.pullreports.com/catalog-1.7.0" id="class" name="Class Reports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.pullreports.com/catalog-1.7.0 https://www.pullreports.com/docs/xsd/pullreports-catalog-1.7.0.xsd"> <report id="student-information" name="Student Information"> <export_config defaultColumns="firstn,lastn"/> <table id="student" name="class_info.student" displayName="Student" primaryKeyColumns="id"> <column id="id" name="id" displayName="Student ID" paramType="java.lang.Integer" export="false"/> <column id="firstn" name="first_name" displayName="First Name"/> <column id="lastn" name="last_name" displayName="Last Name"/> <column id="height_in" name="height_inches" displayName="Height (in)" paramType="java.lang.Double"/> <column id="bdate" name="birth_date" displayName="Birth Date" paramType="java.sql.Date"/> <column id="active" name="is_active" displayName="Active?" paramType="java.lang.Boolean" export="false"/> <pre_filter>@active=true</pre_filter> <relationship> <join_column columnName="student_id" referencedColumnName="id" /> <table id="assignment" displayName="Assignment" name="class_info.assignment"> <column id="id" name="id" displayName="Assignment ID" paramType="java.lang.Integer"/> <column id="grade" name="grade" displayName="Grade"/> <column id="name" name="name" displayName="Name"/> <relationship join="inner" cardinality="one"> <join_column columnName="class_id" referencedColumnName="id" /> <table id="class" displayName="Class" name="class_info.class"> <column id="id" name="id" displayName="Class ID" paramType="java.lang.Integer" export="false"/> <column id="name" name="name" displayName="Class Name"/> </table> </relationship> </table> </relationship> </table> </report> </catalog>
Now that the class
table is part of the report join tree,
we can include the columns of the class
table into the Export Report REST API
export result by adding the /student/assignment/class
table resource path
to the columns
parameter like so:
/[context]/pullreports/catalog/class/report/student-information/export?columns=/student/assignment;/student/assignment/class
The final relationship type to add to our example data model is a to-many in which the relationship between two tables is captured within an indirection or join table. Join tables have foreign key columns to each table in the relationship and are used to relate tables which are modeled as bi-direction, many-to-many relationships. Of course, in Pull Reports™, joins are always uni-directional from a parent to child table, but the join table must still be configured.
To demonstrate to-many, <join_table> joins, we will add two relationships to our example data model.
The first is between a student
record and
the student's parents recorded within a parent
table.
In this relationship, the student_parent
table is the join table.
The second relationship is between a parent
and the parent's employers
represented by the company
table. In this relationship, the parent_company
table is the join table.
Here is the new UML which includes the parent
, company
, and join tables:
The new Pull Reports™ XML Catalog file uses two <join_table>
s to implement the many-to-many relationships. The
student_parent
join table is a second <relationship>
child of the base, student
table, and parent_company
is within a nested <relationship>
of the parent
table.
Since it has a child, descendant table of cardinality many
, we also specify the
primaryKeyColumns
attribute for the parent
table.
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://www.pullreports.com/catalog-1.7.0" id="class" name="Class Reports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.pullreports.com/catalog-1.7.0 https://www.pullreports.com/docs/xsd/pullreports-catalog-1.7.0.xsd"> <report id="student-information" name="Student Information"> <export_config defaultColumns="firstn,lastn"/> <table id="student" name="class_info.student" displayName="Student" primaryKeyColumns="id"> <column id="id" name="id" displayName="Student ID" paramType="java.lang.Integer" export="false"/> <column id="firstn" name="first_name" displayName="First Name"/> <column id="lastn" name="last_name" displayName="Last Name"/> <column id="height_in" name="height_inches" displayName="Height (in)" paramType="java.lang.Double"/> <column id="bdate" name="birth_date" displayName="Birth Date" paramType="java.sql.Date"/> <column id="active" name="is_active" displayName="Active?" paramType="java.lang.Boolean" export="false"/> <pre_filter>@active=true</pre_filter> <relationship> <join_column columnName="student_id" referencedColumnName="id" /> <table id="assignment" displayName="Assignment" name="class_info.assignment"> <column id="id" name="id" displayName="Assignment ID" paramType="java.lang.Integer"/> <column id="grade" name="grade" displayName="Grade"/> <column id="name" name="name" displayName="Name"/> <relationship join="inner" cardinality="one"> <join_column columnName="class_id" referencedColumnName="id" /> <table id="class" displayName="Class" name="class_info.class"> <column id="id" name="id" displayName="Class ID" paramType="java.lang.Integer" export="false"/> <column id="name" name="name" displayName="Class Name"/> </table> </relationship> </table> </relationship> <relationship> <join_table name="class_info.student_parent"> <join_columns> <join_column columnName="student_id" referencedColumnName="id" /> </join_columns> <inverse_join_columns> <join_column columnName="parent_id" referencedColumnName="id" /> </inverse_join_columns> </join_table> <table id="parent" displayName="Parent" name="class_info.parent" primaryKeyColumns="id"> <column id="id" name="id" displayName="Parent ID" paramType="java.lang.Integer"/> <column id="firstn" name="first_name" displayName="Parent First Name"/> <column id="lastn" name="last_name" displayName="Parent Last Name"/> <column id="phone" name="phone" displayName="Phone"/> <relationship> <join_table name="class_info.parent_company"> <join_columns> <join_column columnName="parent_id" referencedColumnName="id" /> </join_columns> <inverse_join_columns> <join_column columnName="company_id" referencedColumnName="id" /> </inverse_join_columns> </join_table> <table id="company" displayName="Company" name="class_info.company"> <column id="id" name="id" displayName="Company ID" paramType="java.lang.Integer" export="false"/> <column id="name" name="name" displayName="Company"/> </table> </relationship> </table> </relationship> </table> </report> </catalog>
Now that the parent
and company
tables are part of the report's join tree,
it is possible to expand our previous Export Report REST API URL and include the new tables within the export
results with this columns
parameter:
/[context]/pullreports/catalog/class/report/student-information/export?columns=/student/assignment;/student/assignment/class;/student/parent;/student/parent/company
However, adding multiple to-many relationships to the same export result returns the
cross product of the joins. In this case, the export results would contain one row for each
combination of the assignment
, parent
, and company
tables.
A more useful export would be to export each to-many relationship
separately. For example:
/[context]/pullreports/catalog/class/report/student-information/export?columns=/student/parent;/student/parent/company
and
/[context]/pullreports/catalog/class/report/student-information/export?columns=/student/assignment;/student/assignment/class
So far in this tutorial, each <relationship>
join is between a parent and child table.
However, it is also possible to create join relationships between a child table and an ancestor table
farther away in the join tree via the <join_column>
referencedTablePath
attribute. To demonstrate a relationship
join to a grandparent, ancestor table, we will once again expand the data model to include
a new table, student_assessment
.
The student_assessment
table contains records of each student's assessment, or opinion, of
the classes in which they enroll. The student_assessment
table has a foreign key to both
student
and class
and could be added to the report
join tree as a relationship child of either table. For this example, we will add
student_assessment
as a relationship child of the class
table and configure a join to the grandparent student
table.
Here is the new UML which includes the student_assessment
table:
To add the student_assessment
table as a child relationship of class
,
use the to-many, <join_column>
relationship type we used to join assignment
to student
.
In this case however, we will use two <join_column>
elements. The first will join student_assessment.class_id
to class.id
, and the second will join student_assessment.student_id
to
student.id
. The later <join_column>
must use the referencedTablePath
attribute
to specify the table resource path of the table which has the referencedColumnName
, /student
.
The new Pull Reports™ XML Catalog file is now:
<?xml version="1.0" encoding="UTF-8"?> <catalog xmlns="http://www.pullreports.com/catalog-1.7.0" id="class" name="Class Reports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.pullreports.com/catalog-1.7.0 https://www.pullreports.com/docs/xsd/pullreports-catalog-1.7.0.xsd"> <report id="student-information" name="Student Information"> <export_config defaultColumns="firstn,lastn"/> <table id="student" name="class_info.student" displayName="Student" primaryKeyColumns="id"> <column id="id" name="id" displayName="Student ID" paramType="java.lang.Integer" export="false"/> <column id="firstn" name="first_name" displayName="First Name"/> <column id="lastn" name="last_name" displayName="Last Name"/> <column id="height_in" name="height_inches" displayName="Height (in)" paramType="java.lang.Double"/> <column id="bdate" name="birth_date" displayName="Birth Date" paramType="java.sql.Date"/> <column id="active" name="is_active" displayName="Active?" paramType="java.lang.Boolean" export="false"/> <pre_filter>@active=true</pre_filter> <relationship> <join_column columnName="student_id" referencedColumnName="id" /> <table id="assignment" displayName="Assignment" name="class_info.assignment"> <column id="id" name="id" displayName="Assignment ID" paramType="java.lang.Integer"/> <column id="grade" name="grade" displayName="Grade"/> <column id="name" name="name" displayName="Name"/> <relationship join="inner" cardinality="one"> <join_column columnName="class_id" referencedColumnName="id" /> <table id="class" displayName="Class" name="class_info.class"> <column id="id" name="id" displayName="Class ID" paramType="java.lang.Integer" export="false"/> <column id="name" name="name" displayName="Class Name"/> <relationship> <join_column columnName="class_id" referencedColumnName="id"/> <join_column columnName="student_id" referencedColumnName="id" referencedTablePath="/student"/> <table id="student_assessment" displayName="Student Assessment" name="class_info.student_assessment"> <column id="rating" name="rating" displayName="Rating" paramType="java.lang.Integer"/> <column id="assessment" name="assessment" displayName="Assessment"/> <column id="assessment_date" name="assessment_date" displayName="Assessment Date" paramType="java.sql.Date"/> </table> </relationship> </table> </relationship> </table> </relationship> <relationship> <join_table name="class_info.student_parent"> <join_columns> <join_column columnName="student_id" referencedColumnName="id" /> </join_columns> <inverse_join_columns> <join_column columnName="parent_id" referencedColumnName="id" /> </inverse_join_columns> </join_table> <table id="parent" displayName="Parent" name="class_info.parent" primaryKeyColumns="id"> <column id="id" name="id" displayName="Parent ID" paramType="java.lang.Integer"/> <column id="firstn" name="first_name" displayName="Parent First Name"/> <column id="lastn" name="last_name" displayName="Parent Last Name"/> <column id="phone" name="phone" displayName="Phone"/> <relationship> <join_table name="class_info.parent_company"> <join_columns> <join_column columnName="parent_id" referencedColumnName="id" /> </join_columns> <inverse_join_columns> <join_column columnName="company_id" referencedColumnName="id" /> </inverse_join_columns> </join_table> <table id="company" displayName="Company" name="class_info.company"> <column id="id" name="id" displayName="Company ID" paramType="java.lang.Integer" export="false"/> <column id="name" name="name" displayName="Company"/> </table> </relationship> </table> </relationship> </table> </report> </catalog>
So far in this tutorial, all examples have been XML Catalog files. Here is a
Catalog Configuration Java API CatalogConfigurationFactory
which is identical to the final XML Catalog file.
package com.pullreports.examples.tutorial;
import com.pullreports.export.request.FilterValue;
import com.pullreports.export.request.Operator;
import com.pullreports.model.Cardinality;
import com.pullreports.model.CatalogId;
import com.pullreports.model.ColumnId;
import com.pullreports.model.Join;
import com.pullreports.model.JoinColumn;
import com.pullreports.model.JoinTable;
import com.pullreports.model.ParamType;
import com.pullreports.model.ReportId;
import com.pullreports.model.TableId;
import com.pullreports.model.TablePath;
import com.pullreports.model.config.CatalogConfiguration;
import com.pullreports.model.config.CatalogConfigurationFactory;
import com.pullreports.model.config.ColumnConfiguration;
import com.pullreports.model.config.JoinColumnsRelationshipConfiguration;
import com.pullreports.model.config.JoinTableRelationshipConfiguration;
import com.pullreports.model.config.PreFilter;
import com.pullreports.model.config.RelationshipConfiguration;
import com.pullreports.model.config.ReportConfiguration;
import com.pullreports.model.config.TableConfiguration;
import com.pullreports.model.exportconfig.ExportConfiguration;
import jakarta.servlet.ServletContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class StudentTutorial2CatalogConfigurationFactory implements CatalogConfigurationFactory {
@Override
public CatalogConfiguration makeCatalog(ServletContext servletContext) {
ReportConfiguration studentReportConfiguration = new StudentReportConfigurationBuilder().build();
List<ReportConfiguration> reportConfigurations = Collections.singletonList(studentReportConfiguration);
return new CatalogConfiguration(new CatalogId("class"),"Class Reports",reportConfigurations);
}
private static class StudentReportConfigurationBuilder extends ReportConfiguration.Builder {
StudentReportConfigurationBuilder(){
super(new ReportId("student-information"),"Student Information"
,new StudentTableConfigurationBuilder().build());
setExportConfiguration(
new ExportConfiguration.Builder().setDefaultColumns(Arrays.asList(
StudentTableConfigurationBuilder.FIRSTN_COLUMN_CONFIGURATION.getId()
,StudentTableConfigurationBuilder.LASTN_COLUMN_CONFIGURATION.getId()))
.build()).build();
}
}
private final static class StudentTableConfigurationBuilder extends TableConfiguration.Builder {
static final ColumnConfiguration ID_COLUMN_CONFIGURATION,FIRSTN_COLUMN_CONFIGURATION
,LASTN_COLUMN_CONFIGURATION,ACTIVE_COLUMN_CONFIGURATION;
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ID_COLUMN_CONFIGURATION = new ColumnConfiguration.Builder(
new ColumnId("id"),"id").setDisplayName("Student ID")
.setParamType(ParamType.INTEGER).setExport(false).build();
FIRSTN_COLUMN_CONFIGURATION = new ColumnConfiguration.Builder(
new ColumnId("firstn"),"first_name").setDisplayName("First Name").build();
LASTN_COLUMN_CONFIGURATION = new ColumnConfiguration.Builder(
new ColumnId("lastn"),"last_name").setDisplayName("Last Name").build();
ColumnConfiguration heightInColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("height_in"),"height_inches").setParamType(ParamType.DOUBLE)
.setDisplayName("Height (in)").build();
ColumnConfiguration bdateColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("bdate"),"birth_date").setParamType(ParamType.DATE)
.setDisplayName("Birth Date").build();
ACTIVE_COLUMN_CONFIGURATION = new ColumnConfiguration.Builder(
new ColumnId("active"),"active").setDisplayName("Active?")
.setParamType(ParamType.BOOLEAN).setExport(false).build();
COLUMN_CONFIGURATIONS = Arrays.asList(
ID_COLUMN_CONFIGURATION,FIRSTN_COLUMN_CONFIGURATION,LASTN_COLUMN_CONFIGURATION
,heightInColumnConfiguration,ACTIVE_COLUMN_CONFIGURATION
,bdateColumnConfiguration);
}
StudentTableConfigurationBuilder(){
super(new TableId("student"),"Student",COLUMN_CONFIGURATIONS);
setName("class_info.student");
PreFilter activePreFilter = new PreFilter(ACTIVE_COLUMN_CONFIGURATION.getId()
,Operator.EQUALS, FilterValue.asList(Boolean.TRUE));
setPreFilters(Collections.singletonList(activePreFilter));
RelationshipConfiguration assignmentRelationship =
new JoinColumnsRelationshipConfiguration.Builder(new AssignmentTableConfigurationBuilder().build()
,Collections.singletonList(new JoinColumn("student_id","id"))).build();
RelationshipConfiguration parentRelationship =
new JoinTableRelationshipConfiguration.Builder(new ParentTableConfigurationBuilder().build()
,new JoinTable("class_info.student_parent"
,Collections.singletonList(new JoinColumn("student_id","id"))
,Collections.singletonList(new JoinColumn("parent_id","id")))).build();
setRelationshipConfigurations(Arrays.asList(assignmentRelationship,parentRelationship));
setPrimaryKeyColumnIds(Collections.singleton(ID_COLUMN_CONFIGURATION.getId()));
}
}
private final static class AssignmentTableConfigurationBuilder extends TableConfiguration.Builder {
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ColumnConfiguration idColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("id"),"id").setDisplayName("Assignment ID")
.setParamType(ParamType.INTEGER).build();
ColumnConfiguration gradeColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("grade"),"grade").setDisplayName("Grade").build();
ColumnConfiguration nameColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("name"),"name").setDisplayName("Name").build();
COLUMN_CONFIGURATIONS = Arrays.asList(
idColumnConfiguration,gradeColumnConfiguration,nameColumnConfiguration);
}
AssignmentTableConfigurationBuilder(){
super(new TableId("assignment"),"Assignment",COLUMN_CONFIGURATIONS);
setName("class_info.assignment");
RelationshipConfiguration classRelationship =
new JoinColumnsRelationshipConfiguration.Builder(new ClassTableConfigurationBuilder().build()
,Collections.singletonList(new JoinColumn("class_id","id")))
.setJoin(Join.INNER).setCardinality(Cardinality.ONE).build();
setRelationshipConfigurations(Collections.singletonList(classRelationship));
}
}
private final static class ClassTableConfigurationBuilder extends TableConfiguration.Builder {
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ColumnConfiguration idColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("id"),"id").setDisplayName("Class ID")
.setParamType(ParamType.INTEGER).setExport(false).build();
ColumnConfiguration nameColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("name"),"name").setDisplayName("Class Name").build();
COLUMN_CONFIGURATIONS = Arrays.asList(
idColumnConfiguration,nameColumnConfiguration);
}
ClassTableConfigurationBuilder(){
super(new TableId("class"),"Class",COLUMN_CONFIGURATIONS);
setName("class_info.class");
RelationshipConfiguration studentAssessmentRelationship =
new JoinColumnsRelationshipConfiguration.Builder(new StudentAssessmentTableConfigurationBuilder().build()
,Arrays.asList(new JoinColumn("class_id","id")
,new JoinColumn("student_id","id",new TablePath("/student")))).build();
setRelationshipConfigurations(Collections.singletonList(studentAssessmentRelationship));
}
}
private final static class StudentAssessmentTableConfigurationBuilder extends TableConfiguration.Builder {
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ColumnConfiguration ratingColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("rating"),"rating").setDisplayName("Rating")
.setParamType(ParamType.INTEGER).build();
ColumnConfiguration assessmentColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("assessment"),"assessment").setDisplayName("Assessment").build();
ColumnConfiguration assessmentDateColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("assessment_date"),"assessment_date").setParamType(ParamType.DATE)
.setDisplayName("Assessment Date").build();
COLUMN_CONFIGURATIONS = Arrays.asList(
ratingColumnConfiguration,assessmentColumnConfiguration
,assessmentDateColumnConfiguration);
}
StudentAssessmentTableConfigurationBuilder(){
super(new TableId("student_assessment"),"Student Assessment",COLUMN_CONFIGURATIONS);
setName("class_info.student_assessment");
}
}
private final static class ParentTableConfigurationBuilder extends TableConfiguration.Builder {
private static final ColumnConfiguration ID_COLUMN_CONFIGURATION;
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ID_COLUMN_CONFIGURATION = new ColumnConfiguration.Builder(
new ColumnId("id"),"id").setDisplayName("Parent ID")
.setParamType(ParamType.INTEGER).build();
ColumnConfiguration firstnColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("firstn"),"first_name").setDisplayName("First Name").build();
ColumnConfiguration lastnColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("lastn"),"last_name").setDisplayName("Last Name").build();
ColumnConfiguration phoneColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("phone"),"phone").setDisplayName("Phone").build();
COLUMN_CONFIGURATIONS = Arrays.asList(
ID_COLUMN_CONFIGURATION,firstnColumnConfiguration
,lastnColumnConfiguration,phoneColumnConfiguration);
}
ParentTableConfigurationBuilder(){
super(new TableId("parent"),"Parent",COLUMN_CONFIGURATIONS);
setName("class_info.parent");
RelationshipConfiguration companyRelationship =
new JoinTableRelationshipConfiguration.Builder(new CompanyTableConfigurationBuilder().build()
,new JoinTable("class_info.parent_company"
,Collections.singletonList(new JoinColumn("parent_id","id"))
,Collections.singletonList(new JoinColumn("company_id","id")))).build();
setRelationshipConfigurations(Collections.singletonList(companyRelationship));
setPrimaryKeyColumnIds(Collections.singleton(ID_COLUMN_CONFIGURATION.getId()));
}
}
private final static class CompanyTableConfigurationBuilder extends TableConfiguration.Builder {
private static final List<ColumnConfiguration> COLUMN_CONFIGURATIONS;
static {
ColumnConfiguration idColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("id"),"id").setDisplayName("Company ID")
.setParamType(ParamType.INTEGER).setExport(false).build();
ColumnConfiguration nameColumnConfiguration = new ColumnConfiguration.Builder(
new ColumnId("name"),"name").setDisplayName("Company").build();
COLUMN_CONFIGURATIONS = Arrays.asList(
idColumnConfiguration,nameColumnConfiguration);
}
CompanyTableConfigurationBuilder(){
super(new TableId("company"),"Company",COLUMN_CONFIGURATIONS);
setName("class_info.company");
}
}
}
This concludes the tutorial regarding <relationship>
configuration.
Continue to Tutorial 3 learn about additional
<column>
configuration capabilities.