हम जेपीए 2 पर आधारित जावा वेब परियोजना पर काम कर रहे हैं के लिए अद्वितीय उल्लंघन अपवाद प्रचार, हाइबरनेट, स्प्रिंग 3 और JSF 2 बिलाव 7 में चल रहे हम डाटाबेस के रूप में Oracle 11g उपयोग कर रहे हैं।सर्वश्रेष्ठ अभ्यास यूआई
हम वर्तमान दृष्टिकोण पर एक बहस पकड़े हुए हैं यूआई के लिए उपयोगकर्ता के अनुकूल संदेश के रूप में डेटाबेस बाधा के उल्लंघन को भरने के लिए। कम या ज्यादा हम दो तरीकों से देखते हैं, दोनों वास्तव में संतोषजनक नहीं हैं। क्या कोई कुछ सलाह दे सकता है?
दृष्टिकोण 1 - प्रोग्राम के रूप में सत्यापित करें और फेंक विशिष्ट अपवाद
CountryService.java में प्रत्येक अद्वितीय बाधा सत्यापित किया जाएगा, और एक इसी अपवाद फेंक दिया है। अपवादों को एक बैकिंग बीन में व्यक्तिगत रूप से संभाला जाता है।
लाभ: समझते हैं और बनाए रखने के लिए आसान। विशिष्ट उपयोगकर्ता संदेश संभव है।
नुकसान: अच्छे संदेश रखने के लिए बहुत सारे कोड। असल में सभी डीबी प्रतिबंध आवेदन में फिर से लिखे गए हैं। बहुत सारे प्रश्न - अनावश्यक डीबी लोड।
@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);
}
}
देखें के समर्थन बीन में आप अपवाद संभाल:
@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 - डेटाबेस बाधा उल्लंघन
लाभ का पता लगाने के चलो: नहीं बॉयलर प्लेट कोड। डीबी के लिए कोई अनावश्यक प्रश्न नहीं। डेटा बाधा तर्क का कोई डुप्लिकेशन नहीं।
नुकसान: निर्भरता डीबी में नामों में रोके, तो स्कीमा की पीढ़ी के माध्यम से संभव नहीं हाइबरनेट। इनपुट घटकों को संदेश बाध्य करने के लिए तंत्र की आवश्यकता होती है (उदा। हाइलाइटिंग के लिए)।
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;
}
}
आप अभी भी दृष्टिकोण 1 में बाधा उल्लंघन का पता लगाने के लिए डेटाबेस पर भरोसा कर रहे हैं, यदि उपयोगकर्ता अद्वितीय जांच के बाद डुप्लिकेट देश बचाता है लेकिन दूसरे उपयोगकर्ता की बचत से पहले। – ken
हम यहां समवर्ती मुद्दे से अवगत हैं। हमारे उपयोग के मामलों के लिए यह अनिवार्य नहीं है।यह पर्याप्त है, अगर 90% मामलों में संदेश विशिष्ट है। यदि असाधारण मामलों में, डीबी द्वारा एक अधिक सामान्य संदेश ट्रिगर किया जाता है इससे कोई फर्क नहीं पड़ता। – fischermatte
मैंने दृष्टिकोण 1 – fischermatte