我使用Spring Data JPA为项目保存User对象。
我在对象中具有电子邮件唯一字段,因此我的模型如下:
@Entity
@Data
@Table(schema = "public", name = "user", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String email;
}
UserRepository:
public interface UserRepository extends PagingAndSortingRepository<User, Integer>, JpaSpecificationExecutor<User> {
List<User> findAllByAddressesContaining(Address address);
User findByEmailIgnoreCase(String email);
List<User> findAllByRoles_id(int id);
}
当我尝试使用userRepository.save(user)
用DB中已经存在的电子邮件保存用户对象时
它可以工作,因此可以更新数据库中现有的用户对象。
我希望在发生唯一约束冲突而不是新对象更新的情况下引发异常,因此我将能够从我的spring MVC控制器发送409 CONFLICT
状态。
如何以最有效和“正确”的方式实现这一目标?
答案 0 :(得分:0)
您可以直接做一件事情,而不是直接保存!您可以创建将emailId作为参数并返回整数的自定义方法,例如... public int getCountForEmailId(String emailId);通过传递本机查询或HQL或JPQ,然后首先检查是否存在任何已发送电子邮件的ID,如果返回计数> 0,则可以返回该ID,并从控制器引发自定义异常。我希望您很清楚。
答案 1 :(得分:0)
在对象模型中此表达式的事实
uniqueConstraints = @UniqueConstraint (columnNames = "email")
使用并不意味着在表中确实创建了该列的约束。
文档: ...使用@UniqueConstraint批注指定对于主表或辅助表,将唯一约束包括在生成的DDL中。 ...
这并不意味着将在运行时检查某些内容。 确保此列约束确实存在于数据库表级别。 我猜你用弹簧吗? 您需要使用以下属性:
spring.jpa.hibernate.ddl-auto = none/create/update/validate <- select this
这将在上下文启动时创建/更新/检查架构。 验证-只需将您对实体(@Entity)的定义与数据库模式中描述的内容(类型,列,约束等)进行比较,例如,如果未向该模式中添加任何约束,则会出现错误。>
在此列中添加数据约束后,每次收到约束违例异常时都会出现。