我们正在开发基于JPA 2、Hibernate、Spring 3和JSF 2的Java Web项目,并在Tomcat 7中运行。我们使用Oracle 11g作为数据库。
目前,我们正在就如何将数据库约束违规作为用户友好的信息显示到UI上展开讨论。更或者我们看到两种方法,但都不够令人满意。请问是否有人能给出建议? 方法1 - 编程方式验证并抛出特定异常 在CountryService.java中,每个唯一约束都将得到验证,并抛出相应的异常。这些异常会在后备bean中单独处理。 优点: 容易理解和维护。可以提供特定的用户信息。 缺点: 很多代码只是为了呈现美观的信息。基本上所有DB约束都要在应用程序中重新编写。很多查询-不必要的数据库负载。
目前,我们正在就如何将数据库约束违规作为用户友好的信息显示到UI上展开讨论。更或者我们看到两种方法,但都不够令人满意。请问是否有人能给出建议? 方法1 - 编程方式验证并抛出特定异常 在CountryService.java中,每个唯一约束都将得到验证,并抛出相应的异常。这些异常会在后备bean中单独处理。 优点: 容易理解和维护。可以提供特定的用户信息。 缺点: 很多代码只是为了呈现美观的信息。基本上所有DB约束都要在应用程序中重新编写。很多查询-不必要的数据库负载。
@Service("countryService")
public class CountryServiceImpl implements CountryService {
@Inject
private CountryRepository countryRepository;
@Override
public Country saveCountry(Country country) throws NameUniqueViolationException, IsoCodeUniqueViolationException, UrlUniqueViolationException {
if (!isUniqueNameInDatabase(country)) {
throw new NameUniqueViolationException();
}
if (!isUniqueUrl(country)) {
throw new UrlUniqueViolationException();
}
if (!isUniqueIsoCodeInDatabase(country)) {
throw new IsoCodeUniqueViolationException();
}
return countryRepository.save(country);
}
}
在视图的后端Bean中处理异常:
@Component
@Scope(value = "view")
public class CountryBean {
private Country country;
@Inject
private CountryService countryService;
public void saveCountryAction() {
try {
countryService.saveCountry(country);
} catch (NameUniqueViolationException e) {
FacesContext.getCurrentInstance().addMessage("name", new FacesMessage("A country with the same name already exists."));
} catch (IsoCodeUniqueViolationException e) {
FacesContext.getCurrentInstance().addMessage("isocode", new FacesMessage("A country with the same isocode already exists."));
} catch (UrlUniqueViolationException e) {
FacesContext.getCurrentInstance().addMessage("url", new FacesMessage("A country with the same url already exists."));
} catch (DataIntegrityViolationException e) {
// update: in case of concurrent modfications. should not happen often
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("The country could not be saved."));
}
}
}
方法2-让数据库检测约束违规
优点:没有样板代码。没有不必要的查询到数据库。不重复数据约束逻辑。
缺点:依赖于数据库中的约束名称,因此无法通过Hibernate生成模式。需要机制将消息绑定到输入组件(例如用于突出显示)。
public class DataIntegrityViolationExceptionsAdvice {
public void afterThrowing(DataIntegrityViolationException ex) throws DataIntegrityViolationException {
// extract the affected database constraint name:
String constraintName = null;
if ((ex.getCause() != null) && (ex.getCause() instanceof ConstraintViolationException)) {
constraintName = ((ConstraintViolationException) ex.getCause()).getConstraintName();
}
// create a detailed message from the constraint name if possible
String message = ConstraintMsgKeyMappingResolver.map(constraintName);
if (message != null) {
throw new DetailedConstraintViolationException(message, ex);
}
throw ex;
}
}