Groovy 和 JPA 阻止 Spring Boot CrudRepository 进行插入
Posted
技术标签:
【中文标题】Groovy 和 JPA 阻止 Spring Boot CrudRepository 进行插入【英文标题】:Groovy and JPA preventing Spring Boot CrudRepository from doing inserts 【发布时间】:2018-01-06 03:43:25 【问题描述】:我有一个(Groovy)Spring Boot 应用程序,它与 H2 内存数据库通信(但不认为这很重要)。我有以下GroceryItem
实体:
@MappedSuperclass
abstract class BaseEntity
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id
@Canonical
@TupleConstructor(includeSuperProperties = true)
@ToString(includeSuperProperties = true)
@Entity(name = 'grocery_items')
@AttributeOverrides([
@AttributeOverride(name = "id", column=@Column(name="grocery_item_id"))
])
class GroceryItem extends BaseEntity
@Column(name = 'grocery_item_name')
@NotNull
@Valid
String name
@Column(name = 'grocery_item_qty')
@NotNull
Integer quantity
然后是一个CrudRepository
接口:
interface GroceryItemPersistor extends CrudRepository<GroceryItem, Long>
@Query('FROM grocery_items WHERE grocery_item_name = :name')
GroceryItem findByName(@Param('name') String name)
@Query('FROM grocery_items')
List<GroceryItem> getAllGroceries()
但是由于某种原因,这个CrudRepository
的save(...)
方法只是更新并允许我将一个GroceryItem
插入到数据库中。意思是如果我运行这段代码:
GroceryItem olives = new GroceryItem(1L, '123456', 'Olives', 6)
groceryItemPersistor.save(olives)
List<GroceryItem> allItems = groceryItemPersistor.getAllGroceries()
log.info("There are $allItems.size() grocery items.")
log.info("$allItems.first().name are in there right now")
GroceryItem cheeseWedges = new GroceryItem(2L, '067e6162-3b6f-4ae2-a171-2470b63dff00', 'Cheese Wedges', 4)
groceryItemPersistor.save(cheeseWedges)
allItems = groceryItemPersistor.getAllGroceries()
log.info("There are $allItems.size() grocery items.")
log.info("$allItems.first().name are in there right now")
我在控制台上得到以下输出:
There are 1 grocery items.
Olives are in there right now.
There are 1 grocery items.
Cheese Wedges are in there right now.
我必须在我的GroceryItem
和/或BaseEntity
类中修改什么才能使save(...)
正确插入而不是更新?
【问题讨论】:
【参考方案1】:创建主键为 1 的橄榄项后,您在创建 cheeseWedges 时传递了相同的主键。
GroceryItem cheeseWedges = new GroceryItem(1L, '067e6162-3b6f-4ae2-a171-2470b63dff00', 'Cheese Wedges', 4)
尝试创建新项目时不要设置主键。如果您设置它,JPA 将尝试更新表中具有相同主键的项目。
【讨论】:
感谢@Ishan (+1) 非常 很抱歉这里的混乱,但我犯了 critical 复制-n-粘贴错误。请看我的编辑!我 am 使用 不同 主键 (2L) 保存“Cheese Wedge”,但 JPA/Hibernate/Spring 仍然只允许保存/更新单个项目。 【参考方案2】:我想通了。我正在创建一个主键并保存它,而不是让 JPA 在调用save
时为我创建我的@Generated
键。将我的实体实例更改为具有null
id:
GroceryItem bananas = new GroceryItem(null, '067e6162-3b6f-4ae2-a171-2470b63dff00', 'Bananas', 12)
...修复了这个问题。
【讨论】:
以上是关于Groovy 和 JPA 阻止 Spring Boot CrudRepository 进行插入的主要内容,如果未能解决你的问题,请参考以下文章
当加载 spring-boot 和 spring-data-jpa 时,Hibernate 无法加载 JPA 2.1 Converter
Kotlin,Spring Boot,JPA - 获取通用枚举的值 (E.valueOf(stringValue))