对唯一复合键的验证检查

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-如何使用约束。

我在这里发布了带有解决方案的代码:..