Paths
Kotlin JDSL has the Path
interface to represent a path expression in JPQL. Use path()
and invoke()
to build Path
.
// Book.isbn.value
path(Book::isbn).path(Isbn::value)
path(Book::isbn)(Isbn::value)
// b.isbn.value
entity(Book::class, "b").path(Book::isbn).path(Isbn::value)
entity(Book::class, "b")(Book::isbn)(Isbn::value)
Java entity
path()
and invoke()
can take KProperty1
or KFuction1
as an argument. KFunction1
is useful when you use Java entity with private property and public getter.
@Entity
public class Book {
@Id
private Long id;
private String title;
public String getTitle() {
return title;
}
}
// compile error
path(Book::title)
// Book.title
path(Book::getTitle)
Kotlin JDSL infers the property name from the getter with the following rules:
If the name starts with
is
, use the name as it is.If the name starts with
get
, removeget
and change the first letter to lowercase.Otherwise, use the name as it is.
// Book.isAvailable
path(Book::isAvailable)
// Book.available
path(Book::getAvailable)
If you want to use your own rule, implement JpqlPropertyIntrospector
and provide it to RenderContext
. See Custom DSL for more details. If you are using Spring, see Spring supports also.
class MyIntrospector : JpqlPropertyIntrospector() {
override fun introspect(property: KCallable<*>): JpqlPropertyDescription? {
if (property is KFunction1<*, *>) {
val name = // resolve a name with your own rule
return MyProperty(name)
}
return null
}
private data class MyProperty(
override val name: String,
) : JpqlPropertyDescription
}
val myModule = object : JpqlRenderModule {
override fun setupModule(context: JpqlRenderModule.SetupContext) {
context.prependIntrospector(MyIntrospector())
}
}
val myContext = JpqlRenderContext().registerModule(myModule)
Expression
Path
can be used as Expression
in a select clause or predicate.
// SELECT Book.isbn FROM Book AS Book WHERE Book.isbn.value = :param1
jpql {
select(
path(Book::isbn),
).from(
entity(Book::class),
).where(
path(Book::isbn)(Ibsn::value).eq("01"),
)
}
Treat
Use treat()
to typecast Path
to subclass.
path(EmployeeDepartment::employee).treat(FullTimeEmployee::class)
Last updated
Was this helpful?