Message Boards

Service Builder / Hibernate column naming

thumbnail
Andre Kreienbring, modified 3 Years ago.

Service Builder / Hibernate column naming

Regular Member Posts: 152 Join Date: 12/18/06 Recent Posts
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 :-)
thumbnail
David H Nebinger, modified 3 Years ago.

RE: Service Builder / Hibernate column naming

Liferay Legend Posts: 14919 Join Date: 9/2/06 Recent Posts
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.
thumbnail
Andre Kreienbring, modified 3 Years ago.

RE: Service Builder / Hibernate column naming

Regular Member Posts: 152 Join Date: 12/18/06 Recent Posts
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 withemoticonevicePK 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?
thumbnail
David H Nebinger, modified 3 Years ago.

RE: Service Builder / Hibernate column naming

Liferay Legend Posts: 14919 Join Date: 9/2/06 Recent Posts
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...
alikol kaliko, modified 3 Years ago.

RE: Service Builder / Hibernate column naming

New Member Posts: 5 Join Date: 3/25/20 Recent Posts
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.
abd erakib, modified 2 Years ago.

RE: Service Builder / Hibernate column naming

New Member Post: 1 Join Date: 11/20/21 Recent Posts
Hello. Did you get the answer to your question? I am in the same situation