0
votes

I'm struggling to find any type of documentation on how to query more complex attributes in my models.

For example I have

public class MyEmbedded{
@EmbeddedID
private MyEmbeddedPK embeddedPK;
}

@Embeddable
public class MyEmbeddedPK{

     private Integer age;

     private Integer zip;       
}

In my repository I am implementing the CrudRepository and would expect to be able to do

public List<MyEmbedded> findByageAndZip(String age, String zip);

But that doesn't seem to work. The documentation doesn't really say anything regarding @EmbeddedId's. The same goes for querying a @OneToMany attribute, I never found anything for that.

Documentation I am referencing. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords

Is there any better documentation on how this query creation works?

2

2 Answers

1
votes

I'm not sure if Spring Data Jpa supports this functionality and it seems a bit complex to query based on embedded id properties as it can equally be applicable to state fields of the enclosing entity itself. But this can be achieved easily with JP QL by specifying it with Query and @Param

@Query("SELECT m FROM MyEmbedded m WHERE m.embeddedPK.age = :age AND m.embeddedPK.zip = :zip")
public List<MyEmbedded> findByageAndZip(@Param("age") String age, @Param("zip") String zip);

Also don't forget to specify your repository with the following signature as Spring data runtime needs to know the actual type of the ID class.

@Repository
public interface MyEmbeddedRepository extends CrudRepository<MyEmbedded, MyEmbeddedPK> {..}
1
votes

I think I found my answer, oddly enough it was in the documentation but I just didn't pick up on it. You just need to combine the properties together via camel case. I could have sworn I tried this but apparently I had my cases messed up.

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions

Section 4.4.3. Property expressions

However, you can also define constraints by traversing nested properties. Assume a Person has an Address with a ZipCode. In that case a method name of

List findByAddressZipCode(ZipCode zipCode);

creates the property traversal x.address.zipCode. The resolution algorithm starts with interpreting the entire part (AddressZipCode) as the property and checks the domain class for a property with that name (uncapitalized). If the algorithm succeeds it uses that property. If not, the algorithm splits up the source at the camel case parts from the right side into a head and a tail and tries to find the corresponding property, in our example, AddressZip and Code. If the algorithm finds a property with that head it takes the tail and continue building the tree down from there, splitting the tail up in the way just described. If the first split does not match, the algorithm move the split point to the left (Address, ZipCode) and continues.