PAA
PAA

Reputation: 11975

@DBRef doesn't pull the Data when use Spring Data Mongo

I used the code from : Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is com.mongodb.util.JSONParseException: and now trying to call

Person p = personRepository.findByAddresses_City("London NW1");
System.out.println("PERSON FOR ADDRESS = "+p);

I get the null response.

Also, below query doesn't pull anything.

Query query = new Query(Criteria.where("address.$id").is(2L));
List<Person> l = mongoTemplate.find(query, Person.class);
System.out.println(l);

Here:

db.getCollection('address').find({})

/* 1 */
{
    "_id" : NumberLong(1),
    "address" : "221b Baker Street",
    "city" : "London NW1",
    "state" : "London",
    "zipcode" : NumberLong(12345),
    "_class" : "com.example.demo.model.Address"
}

and db.getCollection('person').find({})

/* 1 */
{
    "_id" : NumberLong(1),
    "name" : "Achilles",
    "age" : 0,
    "addresses" : [],
    "_class" : "com.example.demo.model.Person"
}

/* 2 */
{
    "_id" : NumberLong(2),
    "name" : "Hektor",
    "age" : 0,
    "addresses" : [ 
        {
            "$ref" : "address",
            "$id" : NumberLong(1),
            "$db" : "address"
        }
    ],
    "_class" : "com.example.demo.model.Person"
}

How to solve this error?

@Document(collection = "address")
public class Address {

    @Id
    private long addressId;
    private String address;
    private String city;
    private String state;
    private long zipcode;

    public Address() {
        System.out.println("CAlling default cons");
    }

    @PersistenceConstructor
    public Address(long addressId, String address, String city, String state, long zipcode) {
        this.addressId = addressId;
        this.address = address;
        this.city = city;
        this.state = state;
        this.zipcode = zipcode;
    }
    // setter and getter... toString()..
}

and

@Document
public class Person {
    @Id
    private Long personId;

    private String name;

    private int age;

    @DBRef(db = "address")
    private List<Address> addresses = new ArrayList<>();

    public Person() {
    }

    @PersistenceConstructor
    public Person(Long personId, String name, int age) {
        super();
        this.personId = personId;
        this.name = name;
        this.age = age;
    }
    // setter, getter and toString
}

Upvotes: 1

Views: 1902

Answers (1)

Oliver Drotbohm
Oliver Drotbohm

Reputation: 83051

This works as designed. MongoDB does not allow application level joins via queries, you'd need to use the aggregation framework for more complex queries. Thus, repository queries only allow to find DBRefs by complete value (i.e Address objects) or identifiers.

The second example should work if you you fix the where clause to address.addressId.

P.S.: Please avoid filing tickets just because you don't immediately get an answer here. If you file a ticket, please be sure to attach a sample project with a test case.

Upvotes: 1

Related Questions