简体   繁体   中英

ResultSetJdbcGpsDevice & @SearchableComponent

I'm having an issue with setting up @SearchableComponent objects using org.compass.gps.device.jdbc.ResultSetJdbcGpsDevice and mapping.TableToResourceMapping .

Trying to test this, I set up two tables that map to objects (ignore the id thing unless that's actually causing this issue):

a
id (pk) | name | create_time | update_time
------------------------------------------

b
id (pk|fk) | property1 | property2 | property3
----------------------------------------------

A and B are defined as such:

@Searchable(root=true)
public class A {
    @SearchableId
    private int id;

    @SearchableProperty
    private String name;

    @SearchableProperty
    private long create_time;

    @SearchableProperty
    private long update_time;

    @SearchableComponent
    private B b;

    // getters, setters
}

@Searchable(root=false)
public class B {
    @SearchableId
    private int id;

    @SearchableProperty
    private String property1;

    @SearchableProperty
    private long property2;

    @SearchableProperty
    private String property3;

    // getters, setters
}

Here's how I'm setting everything up:

conf = new CompassConfiguration()
    .setSetting(CompassEnvironment.CONNECTION, "target/index")
    .addClass(A.class)
    .addClass(B.class);
compass = conf.buildCompass();

ResultSetJdbcGpsDevice jdbc = new ResultSetJdbcGpsDevice();
jdbc.setDataSource(ds);
jdbc.setName("sql-device");
jdbc.setMirrorDataChanges(true);

TableToResourceMapping mappingA = new TabbleToResourceMapping("a", "A");
mapping.addIdMapping(new IdColumnToPropertyMapping("id", "id"));
mapping.addDataMapping(new DataColumnToPropertyMapping("name", "name"));
mapping.addDataMapping(new DataColumnToPropertyMapping("create_time", "create_time"));
mapping.addDataMapping(new DataColumnToPropertyMapping("update_time", "update_time"));

TableToResourceMapping mappingB = new TabbleToResourceMapping("b", "B");
mapping.addIdMapping(new IdColumnToPropertyMapping("id", "id"));
mapping.addDataMapping(new DataColumnToPropertyMapping("property1", "property1"));
mapping.addDataMapping(new DataColumnToPropertyMapping("property2", "property2"));
mapping.addDataMapping(new DataColumnToPropertyMapping("property3", "property3"));

jdbc.addMapping(mappingA);
jdbc.addMapping(mappingB);

gps = new SingleCompassGps(compass);
gps.addGpsDevice(jdbc);
gps.start();
gps.index();

With this, I get the following error from Compass:

java.lang.IllegalStateException: {sql-device}: No resource mapping defined in gps mirror compass for alias [B]. Did you defined a jdbc mapping builder?
at org.compass.gps.device.jdbc.ResultSetJdbcGpsDevice.doStart(ResultSetJdbcGpsDevice.java:127)
at org.compass.gps.device.AbstractGpsDevice.start(AbstractGpsDevice.java:124
at org.compass.gps.impl.AbstractCompassGps.start(AbstractCompassGps.java:166)
...

If I set B as root=true it works fine, and I can search for text in fields for both A and B and get stuff back. However, when A is built and returned by the search, its B instance is empty.

If I search for property2:0 then I retrieve instances of B that map to rows where that column is 0, but I ALSO retrieve every instance of A -- because all of their B components are default instances.

How am I supposed to properly set this up? I feel like I might be missing something in the Compass documentation.

After trying to figure this out I worked out the following solution:

TableToResourceMapping mapping = new TabbleToResourceMapping("a", "A");
mapping.setQuery("select * from a join b using (id)");

mapping.addIdMapping(new IdColumnToPropertyMapping("id", "id"));
mapping.addDataMapping(new DataColumnToPropertyMapping("name", "name"));
mapping.addDataMapping(new DataColumnToPropertyMapping("create_time", "create_time"));
mapping.addDataMapping(new DataColumnToPropertyMapping("update_time", "update_time"));

mapping.addDataMapping(new DataColumnToPropertyMapping("property1", "property1"));
mapping.addDataMapping(new DataColumnToPropertyMapping("property2", "property2"));
mapping.addDataMapping(new DataColumnToPropertyMapping("property3", "property3"));

jdbc.addMapping(mapping);

This may not be the right way to do it, but it works. Searching presents me with an instance A that has the correct data in its fields, including an instance B that also has the correct data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM