Message Boards

Service Builder and Database View with DynamicQuery

Kevin Neibarger, modified 4 Years ago.

Service Builder and Database View with DynamicQuery

Regular Member Posts: 105 Join Date: 2/2/18 Recent Posts
I'm having trouble getting a DynamicQuery implementation working with a primary key in a Database View. 
service.xml
<entity name="NPIPopulationProviders" table="PopulationProvider"local-service="true" remote-service="false"persistence-class="com.healthmap.portlet.compass.custom_persistence.CustomPersistenceImpl$NPIPopulationProvidersSessionOverride"cache-enabled="false" data-source="externalDataSource" session-factory="externalSessionFactory" tx-manager="externalTransactionManager">
<column name="NPI" type="long" primary="true" />
<column name="name" db-name="name" type="String" /></entity>

My LocalServiceImpl file
​​​​​​​
if (Validator.isNotNull(npiProvider)) {
junction.add(PropertyFactoryUtil.forName("primaryKey.NPI").eq(npiProvider));
}
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(NPIPopulationProviders.class, this.getClassLoader()).add(junction);

Getting the dreaded and horribly handled exception from Liferay. Typically I just prepend the property name with "primaryKey." like the above, but it does not work.

13:16:10,042 ERROR [http-bio-8080-exec-3][BasePersistenceImpl:244] Caught unexpected exception org.hibernate.QueryException13:16:10,078 ERROR [http-bio-8080-exec-3][ClpSerializer:6485] java.lang.ClassNotFoundException: org.hibernate.QueryExceptionjava.lang.ClassNotFoundException: org.hibernate.QueryExceptionat org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
This just came up yesterday I think on the community slack.

Never use DynamicQueryFactoryUtil.forClass(). That is a legacy method that really IMHO should be marked as deprecated.

Instead, use myLocalService.dynamicQuery() to get a DQ instance correctly instantiated for the right class loader it comes from.

That prepend of "primaryKey." will not be necessary.
Kevin Neibarger, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Regular Member Posts: 105 Join Date: 2/2/18 Recent Posts
Looks like that worked! I wonder what is wrong with forClass? I use it with no errors or exceptions in other places.. 
thumbnail
Olaf Kock, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Liferay Legend Posts: 6403 Join Date: 9/23/08 Recent Posts
Kevin Neibarger:

Looks like that worked! I wonder what is wrong with forClass? I use it with no errors or exceptions in other places.. 
it depends on what classes you use it for: If they're available to the classloader, then it'll work. If they aren't, you're better of getting it from somewhere, where the class you're looking for is really available. And to the service itself, its classes are there.
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
Kevin Neibarger:

Looks like that worked! I wonder what is wrong with forClass? I use it with no errors or exceptions in other places.. 


Since the interfaces come from API but implementation comes from Service jars, you need to have both available. Normally we only 'compileOnly' the API but never the Service.


That's why the DQFU forClass() is problematic; it assumes a well defined class loader w/ all necessary pieces rolled in, and that is not always so easy to do.

Using the XxxLocalService's dynamicQuery() method works every time and gives you an instance with the correct class loaders in place. It is always best to use this method to ensure that, regardless of what happens in the future, the contract w/ the dynamicQuery() method should ensure that you're given a well constructed instance that is ready to go.
Kevin Neibarger, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Regular Member Posts: 105 Join Date: 2/2/18 Recent Posts
Thanks for the explanation, I'm going to try to re-factor all code using that forClass() since I know how the this.dynamicQuery() works and makes more sense to use. Documentation around this is hard to find... thanks again!
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Service Builder and Database View with DynamicQuery

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
New blog post up highlighting this and also includes using DQ: https://liferay.dev/blogs/-/blogs/visiting-dynamicquery