【发布时间】:2014-01-06 19:51:26
【问题描述】:
我没有在我的源代码中包含使用硬编码的 Hibernate 属性名称,以避免在更改数据库或 Hibernate 配置时出现潜在的错误。
我总是使用 Hibernate Criteria 和我创建的以下 HibernateUtils.getPropertyName() 方法来完成此操作。
/**
* Get a Hibernate property name.<p>
*
* <b>NOTE:</b> This method assumes all property names start with a lower-case character.
*
* @param methodChecker
* - An ignored value. This parameter is a place-holder for a call to the "get" method for the property of interest.
* @param methodName
* - The name of the "get" method used to retrieve the property of interest
* @return The property name
*/
public static String getPropertyName(Object methodChecker, String methodName)
{
String propertyName;
if (methodName.startsWith("get"))
{
propertyName = methodName.substring(3, 4).toLowerCase(Locale.ENGLISH)
+ methodName.substring(4);
}
else if (methodName.startsWith("is"))
{
propertyName = methodName.substring(2, 3).toLowerCase(Locale.ENGLISH)
+ methodName.substring(3);
}
else
{
throw new IllegalArgumentException("method name did not start with 'is' or 'get'");
}
return propertyName;
}
为了使用它,我将属性的“get”方法调用为第一个参数,然后硬编码第二个属性的“get”方法的名称。
使用这种方法,Hibernate 配置或数据库更改将导致 COMPILE-TIME ERRORS 而不是 RUN-TIME ERRORS。
例如,如果将 vendor 属性重命名为 vendorname,则以下代码将导致 RUN-TIME ERROR。
产品 product = (Product) session.createCriteria(Product.class).add(Property.forName("vendor").eq(vendor)).uniqueResult();
要修复代码,所有出现的 vendor 都必须替换为 vendorname。显然,这很容易出错并且可能非常耗时。
我使用以下语句实现了相同的功能:
Product product = (Product) session.createCriteria(Product.class).add(Property.forName(HibernateUtils.getPropertyName(myProduct.getVendor(), "getVendor")).eq(vendor)).uniqueResult ();
如果将 vendor 属性重命名为 vendorname,第二种方法将导致 COMPILE-TIME ERRORS,因为 getVendor() 方法将更改为getVendorname()。
我想知道是否有其他方法 - 可以让我完全消除 HibernateUtils.getPropertyName()。
谢谢!
【问题讨论】:
-
大多数人会对 bean 名称进行 IDE 重构,这样会很高兴地在不更改字符串的情况下修复方法调用,并且无论如何您都不会看到编译时错误.....这看起来像jUnit 的工作,而不是复杂的代码以防止将来出现拼写错误。
-
dkatzel 在下面提到了同样的问题。这是一个很好的观点。我已经能够通过在生成 Hibernate 类时使用它们并且从不使用 IDE 重构来避免它。绝对是值得注意的事情。谢谢。