对唯一复合键的验证检查
Validation check on unique composite key
我有一个实体 class 的 3 个字段,我不希望它们是唯一的,而是希望将它们用作键的复合字段,该键本身必须是唯一的。
我的 class POJO:
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min=3, max=50)
@Column(name = "NAME", nullable = false)
private String name;
@Size(min=3, max=50)
@Column(name = "A", nullable = false)
private String a;
@Size(min=3, max=50)
@Column(name = "B", nullable = false)
private String b;
@Size(min=3, max=50)
@Column(name = "C", nullable = false)
private String c;
@NotNull
@DateTimeFormat(pattern="dd/MM/yyyy")
@Column(name = "JOINING_DATE", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate joiningDate;
@NotNull
@Digits(integer=8, fraction=2)
@Column(name = "SALARY", nullable = false)
private BigDecimal salary;
@NotEmpty
@Column(name = "SSN", unique=true, nullable = false)
private String ssn;
}
我正在处理表单提交,通过 JSR303 注释验证用户输入。如果验证失败,默认错误消息是 shown.I 配置的 ResourceBundleMessageSource:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.fussa.fyby")
public class AppConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
}
/src/main/resources/messages.properties
Size.employee.name=between {2} and {1} characters long
NotNull.employee.joiningDate=can not be blank
NotNull.employee.salary=are u working for free !
Digits.employee.salary=Only numeric data with max 8 digits and with max 2 precision is allowed
NotEmpty.employee.ssn=can not be blank
typeMismatch=Invalid format
non.unique.ssn=SSN {0} already exist.
我找到了创建唯一密钥的解决方案:
@Table( name = "EMPLOYEE",
uniqueConstraints = { @UniqueConstraint( columnNames = { "A", "B", "C" } ) } )
我的问题是,如果违反了唯一约束,我如何使用 messages.properties 显示消息?
更新 1
@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeDao dao;
//....
public void saveEmployee(Employee employee) {
dao.saveEmployee(employee);
}
}
感谢任何建议..
如果您想使用 Bean Validation,您将需要编写一个自定义约束来验证这三列是否唯一。请注意,这是有问题的。除非您锁定整个 table,否则您总是会遇到这样的问题,即当您的约束验证器检查唯一性时,另一个并发事务会更改数据库。另请参阅此 Whosebug 问题 - Unique constraint with JPA and Bean Validation. There is a blog post on the Validator Wiki 关于 Unique
约束的外观,但它带有刚才提到的警告。验证可能会通过,但在插入期间,由于另一个事务同时修改了数据,您仍然可能会遇到数据库级别的异常(因此您的代码也需要处理这种情况)。此外,对于 Bean Validation 1.1,您可能可以直接注入 SessionFactory
。
我按照以下步骤成功地为一个字段创建了唯一约束验证:
1- 创建约束注释。
2-创建约束验证器。
3-错误信息。
4-如何使用约束。
我在这里发布了带有解决方案的代码:..
我有一个实体 class 的 3 个字段,我不希望它们是唯一的,而是希望将它们用作键的复合字段,该键本身必须是唯一的。 我的 class POJO:
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min=3, max=50)
@Column(name = "NAME", nullable = false)
private String name;
@Size(min=3, max=50)
@Column(name = "A", nullable = false)
private String a;
@Size(min=3, max=50)
@Column(name = "B", nullable = false)
private String b;
@Size(min=3, max=50)
@Column(name = "C", nullable = false)
private String c;
@NotNull
@DateTimeFormat(pattern="dd/MM/yyyy")
@Column(name = "JOINING_DATE", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate joiningDate;
@NotNull
@Digits(integer=8, fraction=2)
@Column(name = "SALARY", nullable = false)
private BigDecimal salary;
@NotEmpty
@Column(name = "SSN", unique=true, nullable = false)
private String ssn;
}
我正在处理表单提交,通过 JSR303 注释验证用户输入。如果验证失败,默认错误消息是 shown.I 配置的 ResourceBundleMessageSource:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.fussa.fyby")
public class AppConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
}
/src/main/resources/messages.properties
Size.employee.name=between {2} and {1} characters long
NotNull.employee.joiningDate=can not be blank
NotNull.employee.salary=are u working for free !
Digits.employee.salary=Only numeric data with max 8 digits and with max 2 precision is allowed
NotEmpty.employee.ssn=can not be blank
typeMismatch=Invalid format
non.unique.ssn=SSN {0} already exist.
我找到了创建唯一密钥的解决方案:
@Table( name = "EMPLOYEE",
uniqueConstraints = { @UniqueConstraint( columnNames = { "A", "B", "C" } ) } )
我的问题是,如果违反了唯一约束,我如何使用 messages.properties 显示消息?
更新 1
@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeDao dao;
//....
public void saveEmployee(Employee employee) {
dao.saveEmployee(employee);
}
}
感谢任何建议..
如果您想使用 Bean Validation,您将需要编写一个自定义约束来验证这三列是否唯一。请注意,这是有问题的。除非您锁定整个 table,否则您总是会遇到这样的问题,即当您的约束验证器检查唯一性时,另一个并发事务会更改数据库。另请参阅此 Whosebug 问题 - Unique constraint with JPA and Bean Validation. There is a blog post on the Validator Wiki 关于 Unique
约束的外观,但它带有刚才提到的警告。验证可能会通过,但在插入期间,由于另一个事务同时修改了数据,您仍然可能会遇到数据库级别的异常(因此您的代码也需要处理这种情况)。此外,对于 Bean Validation 1.1,您可能可以直接注入 SessionFactory
。
我按照以下步骤成功地为一个字段创建了唯一约束验证:
1- 创建约束注释。 2-创建约束验证器。 3-错误信息。 4-如何使用约束。
我在这里发布了带有解决方案的代码: