Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: Service Builder / Hibernate column naming
After having several problems apparently caused by column names... What is the best practice?
For example I have a column that is simply called "id". Hibernate turns this into "id_" in a dynamicQuery and SQL driver moans:
"Unknown column 'this_.id_' in 'field list'" (Note the added underscore...)
I could solve that by adding an explicit "db-name" to the column in service.xml, but here comes the next issue.
Column name is "manufacturer_id". It looks as if the generated model has no problems with this name, because SB generates nicely:
public static final Object[][] TABLE_COLUMNS = {
{"manufacturer_id", Types.VARCHAR}, {"name", Types.VARCHAR}, {"category_name", Types.VARCHAR}
};
in the DeviceModelImpl of the API. But when a dynamicQuery is executed the log states an error like:
org.hibernate.QueryException: could not resolve property: manufacturer_id of: openHAB.service.builder.model.impl.DeviceImpl
So what ist best practice here to NOT run into such annoying naming issues?
Naming columns following a specific strategy, avoiding any reserved word? What is the best strategy and which words have to be avoided?
Setting "db-name" on every column in service.xml? Hm.. I guess SB replaces column names for a reason...
Implement something in "DeviceImpl" in my above example? Apparently that wasn't necessary until I started using a dynamicQuery...
Configuring a different Hibernate naming strategy? Where can I do that and which rules to follow then?
I'm looking forward to your best practices :-)
For example I have a column that is simply called "id". Hibernate turns this into "id_" in a dynamicQuery and SQL driver moans:
"Unknown column 'this_.id_' in 'field list'" (Note the added underscore...)
I could solve that by adding an explicit "db-name" to the column in service.xml, but here comes the next issue.
Column name is "manufacturer_id". It looks as if the generated model has no problems with this name, because SB generates nicely:
public static final Object[][] TABLE_COLUMNS = {
{"manufacturer_id", Types.VARCHAR}, {"name", Types.VARCHAR}, {"category_name", Types.VARCHAR}
};
in the DeviceModelImpl of the API. But when a dynamicQuery is executed the log states an error like:
org.hibernate.QueryException: could not resolve property: manufacturer_id of: openHAB.service.builder.model.impl.DeviceImpl
So what ist best practice here to NOT run into such annoying naming issues?
Naming columns following a specific strategy, avoiding any reserved word? What is the best strategy and which words have to be avoided?
Setting "db-name" on every column in service.xml? Hm.. I guess SB replaces column names for a reason...
Implement something in "DeviceImpl" in my above example? Apparently that wasn't necessary until I started using a dynamicQuery...
Configuring a different Hibernate naming strategy? Where can I do that and which rules to follow then?
I'm looking forward to your best practices :-)
Best practice in defining <entity /> and <column /> values is to adhere to Java naming standards. This typically means using mixed case, capital-first for the entity but lowercase first for the column. This defines an entity according to Java POJO practices which is what your entity will appear as to regular Java code.
Your DBA may have different requirements for tables and column names. For those cases, you should use the db-name attribute to specify a name format that adheres to the DBA requirements.
Could this mean a db-name attribute on each <column />? Sure can, and I've done it.
The underscore is appended to certain names because while your database may be okay with a column named "id", in others it is a reserved word and would cause Liferay issues if trying to use. Since Liferay is database agnostic, it treats all of these various reserved words in the same way, appending an underscore to the name. The db-name attribute is the only way to bypass that, but if you deploy to a DB where "id" is a reserved word, you will be stuck dealing with the error.
Your DBA may have different requirements for tables and column names. For those cases, you should use the db-name attribute to specify a name format that adheres to the DBA requirements.
Could this mean a db-name attribute on each <column />? Sure can, and I've done it.
The underscore is appended to certain names because while your database may be okay with a column named "id", in others it is a reserved word and would cause Liferay issues if trying to use. Since Liferay is database agnostic, it treats all of these various reserved words in the same way, appending an underscore to the name. The db-name attribute is the only way to bypass that, but if you deploy to a DB where "id" is a reserved word, you will be stuck dealing with the error.
OK, I got that! Thanks.
But regarding this error:
org.hibernate.QueryException: could not resolve property: manufacturer_id of: [myPackage].model.impl.DeviceImpl
doing something like
DynamicQuery deviceQuery = DeviceLocalServiceUtil.dynamicQuery();
deviceQuery.add(RestrictionsFactoryUtil.eq("manufacturer_id", manufacturer_Id))
it turns out that it's not working because manufacturer_id is part of a composite primary key as defined in the service.xml like
<!-- PK fields -->
<column name="manufacturer_id" db-name="manufacturer_id" primary="true" type="String" />
<column name="name" db-name="name" primary="true" type="String" />
This generates a module.hbm.xml that looks with this:
<composite-id class="[myPackage].service.persistence.DevicePK" name="primaryKey">
<key-property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="manufacturer_id" type="com.liferay.portal.dao.orm.hibernate.StringType" />
<key-property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="name" type="com.liferay.portal.dao.orm.hibernate.StringType" />
</composite-id>
And now I'm going crazy because the dynamicQuery is not working (grrrr)
Already tried with
evicePK devicePK = new DevicePK();
.setProjection(ProjectionFactoryUtil.property(devicePK.getManufacturerId())) .setProjection(ProjectionFactoryUtil.property(devicePK.getName()));
to simply retriev the values from the DB. But that causes a NullpointerException.
How to use composite primary keys in dynamic queries?
But regarding this error:
org.hibernate.QueryException: could not resolve property: manufacturer_id of: [myPackage].model.impl.DeviceImpl
doing something like
DynamicQuery deviceQuery = DeviceLocalServiceUtil.dynamicQuery();
deviceQuery.add(RestrictionsFactoryUtil.eq("manufacturer_id", manufacturer_Id))
it turns out that it's not working because manufacturer_id is part of a composite primary key as defined in the service.xml like
<!-- PK fields -->
<column name="manufacturer_id" db-name="manufacturer_id" primary="true" type="String" />
<column name="name" db-name="name" primary="true" type="String" />
This generates a module.hbm.xml that looks with this:
<composite-id class="[myPackage].service.persistence.DevicePK" name="primaryKey">
<key-property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="manufacturer_id" type="com.liferay.portal.dao.orm.hibernate.StringType" />
<key-property access="com.liferay.portal.dao.orm.hibernate.LiferayPropertyAccessor" name="name" type="com.liferay.portal.dao.orm.hibernate.StringType" />
</composite-id>
And now I'm going crazy because the dynamicQuery is not working (grrrr)
Already tried with

.setProjection(ProjectionFactoryUtil.property(devicePK.getManufacturerId())) .setProjection(ProjectionFactoryUtil.property(devicePK.getName()));
to simply retriev the values from the DB. But that causes a NullpointerException.
How to use composite primary keys in dynamic queries?
I would avoid composite keys, especially when they are natural keys.
Stick with a surrogate key, as a long value, define a finder for your two columns and keep things simple.
Natural keys are always a bad idea for database design...
Stick with a surrogate key, as a long value, define a finder for your two columns and keep things simple.
Natural keys are always a bad idea for database design...
Liferay ships a usage for JAXB in the item. We simply need to design the JVM to search for it as opposed to attempting to search for the default old one. Simply setting the property javax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory ought to do it. You ought to have the option to set it on your condition or executable for the JVM that begins Liferay. It ought to be set of course if later Liferay renditions.
Hello. Did you get the answer to your question? I am in the same situation
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™