Here the final solution I came up with if anyone has a similar issue. Sure not simple and if you don't know it, you are faster with plain string concatenation.
First of I have a many-to-many relationship where the link table has an additional column. The link table entity contains an @EmbeddedId composite id.
(see
http://it4beginners.wordpress.com/2012/10/05/spring-3-and-hibernate-4-for-beginners/ for full details)
to avoid the NullPointerException I had to add @QueryInit("chemicalStructure") to the @EmbeddedId
[code]
@EmbeddedId
@QueryInit("chemicalStructure")
public ChemicalCompoundCompositionID getPk() {
return pk;
}
[/code]
(This part is kind of undesirable to make you entity classes depend on querydsl)
However this lead to the next Problem: hibernate exception because @ is an invalid character.
The solution to this is completely unrelated to querydsl but I will just post it here. I had to extend the Dialect I use an register an additional function.
[code]
public class BingoPostgreSQLDialect extends PostgreSQL82Dialect {
public BingoPostgreSQLDialect() {
registerFunction("issubstructure", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "?1 @ (?2, ?3)::bingo.sub"));
}
}
[/code]
Note that I had to write "issubstructure" all in lower case else it would not work.However in the BooleanTemplate itself you can write it in camel case and it works. A bit strange yes. I assume querydsl or hibernate make everything lower case and hence the function must be lower case. You then need to tell hibernate / JPA to use this custom dialect (in my case in springs application context file) instead fo the default one for your database.
The query then look like this:
[code]
JPAQuery query = new JPAQuery(entityManager);
QChemicalCompound compound = QChemicalCompound.chemicalCompound;
QChemicalCompoundComposition composition = QChemicalCompoundComposition.chemicalCompoundComposition;
QChemicalStructure structure = QChemicalStructure.chemicalStructure;
List<ChemicalCompound> result = query.from(compound)
.innerJoin(compound.composition, composition)
.innerJoin(composition.pk.chemicalStructure, structure)
.where(BooleanTemplate.create("isSubstructure({0},{1},{2}) = true",
structure.structureData,
ConstantImpl.create("c1ccccc1"),
ConstantImpl.create("")))
.list(compound);
return result;
[/code]
Mind "= true" for the isSubstructure function. That is also absolutely required!
On Monday, October 22, 2012 8:38:52 AM UTC+2, Timo Westkämper wrote:
Hi.