Spring Data CrudRepository 的保存抛出 InvocationTargetException
Posted
技术标签:
【中文标题】Spring Data CrudRepository 的保存抛出 InvocationTargetException【英文标题】:Spring Data CrudRepository's save throws InvocationTargetException 【发布时间】:2021-12-16 01:56:00 【问题描述】:我整个周末都在尝试调试这段代码。我有一个 Spring RestController:
import com.tsakirogf.schedu.model.ContactMean;
import com.tsakirogf.schedu.model.DefaultContactMean;
import com.tsakirogf.schedu.model.human.Business;
import com.tsakirogf.schedu.services.BusinessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
import java.util.Set;
@RestController
@RequestMapping("api/v1/business/")
public class BusinessController
@Autowired
BusinessService businessService;
@GetMapping(value = "businesss")
Iterable<Business> list()
Iterable<Business> retVal = businessService.findAll();
return retVal;
@RequestMapping(value = "business", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
Business create(@RequestBody Business business)
CollectionOfContactMethods collectionOfContact = business.getContact();
collectionOfContact.setBusiness(business);
Set<ContactMean> contactMeanSet = collectionOfContact.getContactMeans();
DefaultContactMean defaultContactMeanSet = collectionOfContact.getDefaultContactMean();
defaultContactMeanSet.getCollectionOfContactMethodsDefault().setId(collectionOfContact.getId());
for (ContactMean element : contactMeanSet)
element.setCollectionOfContactMethods(collectionOfContact);
collectionOfContact.setDefaultContactMean(defaultContactMeanSet);
business.setContact(collectionOfContact);
Business retval = businessService.save(business);
return retval;
@RequestMapping(value = "business/id", method = RequestMethod.GET )
Optional<Business> get(@PathVariable Long id)
return businessService.findById(id);
还有服务:
public interface BusinessService extends CrudRepository<Business, Long>
这是模型:
@Table(name = "business")
public class Business
@Id
@Column(name = "business_id", nullable = false)
private Long id;
@JsonProperty("name")
private String name;
@Embedded
@JsonProperty("address")
private Address address;
@OneToMany(mappedBy = "business",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
@JsonProperty("operatives")
@JsonIgnore
Set<Professional> operatives;
@OneToOne(mappedBy = "business",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
optional = false)
@JsonBackReference
@JsonProperty("contact_numbers")
private CollectionOfContactMethods contact;
public Business()
// Getters and Setters
当我发送这样的 POST 请求时:
我从哪里得到以下内容
"时间戳": "2021-11-01T08:59:06.343+00:00", “状态”:500, "error": "内部服务器错误", “路径”:“/api/v1/business/business”
我调试并得到 InvocationTargetException,如下所示 这是控制器,就在 save() 之前似乎抛出:
这里有一个问题:
我发现 this article 在 *** 的 similar event 中发布,但我不认为在这种情况下会发生这种情况,因为我现在只有 H2 数据库。 这是 application.properties 文件:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.hbm2ddl.auto=create
我会很感激任何想法。感谢您的宝贵时间。
【问题讨论】:
可以包含stackstrace吗? 将是我的荣幸 您有一个id
字段,它没有分配给它的生成器。因此,您需要更改它或在保存之前手动将id
分配给对象。
耶稣。我怎么错过了? @M.Deinum 就是这样(@GeneratedValue(strategy = GenerationType.SEQUENCE)),请随时创建答案并明白这一点。你当之无愧。另外,我将保留这个问题,因为这个例外似乎没有什么误导性。
【参考方案1】:
如果您查看上一个屏幕截图,您会看到一条消息,指出有一个没有值的 id
字段。
在您的实体中,您的id
字段声明如下:
@Id
@Column(name = "business_id", nullable = false)
private Long id;
这表明休眠它不应该生成密钥或没有分配给数据库的密钥。这意味着您将需要手动设置id
的值。如果不这样做,您将遇到此异常。
现在我假设这是一个错误,并且您实际上想要一个序列或自动递增的 id
字段。为此添加 @GeneratedValue
注释以添加此行为。
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE))
@Column(name = "business_id", nullable = false)
private Long id;
这将指示 hibernate 在插入实体时使用序列生成id
。如果您的数据库支持identity
列,您可能希望使用GenerationType.IDENTITY
而不是GenerationType.SEQUENCE
。
【讨论】:
以上是关于Spring Data CrudRepository 的保存抛出 InvocationTargetException的主要内容,如果未能解决你的问题,请参考以下文章
@Tailable(spring-data-reactive-mongodb) 等效于 spring-data-r2dbc
如何利用spring data mongodb 进行多条件查询
Spring Data 系列 Spring+JPA(spring-data-commons)
初探 spring data--- spring data 概述
spring-data-jpa 和 spring-boot-starter-data-jpa 的区别
无法将 Spring Data MongoDB + Spring Data JPA 与 Spring Boot 一起使用