保存后刷新并获取实体(JPA/Spring Data/Hibernate) [英] Refresh and fetch an entity after save (JPA/Spring Data/Hibernate)
问题描述
我有这两个简单的实体Something
和Property
.Something
实体与 Property
具有多对一的关系,因此当我创建一个新的 Something
行时,我分配了一个现有的 属性
.
I've these two simple entities Something
and Property
.
The Something
entity has a many-to-one relationship to Property
, so when I create a new Something
row, I assign an existing Property
.
事情:
@Entity
@Table(name = "something")
public class Something implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "owner")
private String owner;
@ManyToOne
private Property property;
// getters and setters
@Override
public String toString() {
return "Something{" +
"id=" + getId() +
", name='" + getName() + "'" +
", owner='" + getOwner() + "'" +
", property=" + getProperty() +
"}";
}
财产:
@Entity
@Table(name = "property")
public class Property implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "shape")
private String shape;
@Column(name = "color")
private String color;
@Column(name = "dimension")
private Integer dimension;
// getters and setters
@Override
public String toString() {
return "Property{" +
"id=" + getId() +
", shape='" + getShape() + "'" +
", color='" + getColor() + "'" +
", dimension='" + getDimension() + "'" +
"}";
}
}
这是SomethingRepository
(Spring):
This is the SomethingRepository
(Spring):
@SuppressWarnings("unused")
@Repository
public interface SomethingRepository extends JpaRepository<Something,Long> {
}
通过 REST 控制器和 JSON,我想创建一个新的 Something
:
Through a REST controller and a JSON, I want to create a new Something
:
@RestController
@RequestMapping("/api")
public class SomethingResource {
private final SomethingRepository somethingRepository;
public SomethingResource(SomethingRepository somethingRepository) {
this.somethingRepository = somethingRepository;
}
@PostMapping("/somethings")
public Something createSomething(@RequestBody Something something) throws URISyntaxException {
Something result = somethingRepository.save(something);
return result;
}
}
这是输入中的 JSON(property
id
1 是数据库中的现有行):
This is the JSON in input (the property
id
1 is an existing row in the database):
{
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1
}
}
问题是:在方法.save(something)
之后,变量result
包含持久化的实体,但没有字段property的字段代码>,已验证(它们是
null
):
The problem is: after the method .save(something)
, the variable result
contains the persisted entity, but without the fields of field property
, validated (they are null
):
输出 JSON:
{
"id": 1,
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1,
"shape": null,
"color": null,
"dimension": null
}
}
我希望在保存操作后验证/返回它们.
I expect that they are validated/returned after the save operation.
要解决此问题,我必须在 REST 控制器中注入/声明 EntityManager
,并调用方法 EntityManager.refresh(something)
(或者我必须调用一个 .findOne(something.getId())
方法来拥有完整的持久化实体):
To workaround this, I have to inject/declare the EntityManager
in the REST controller, and call the method EntityManager.refresh(something)
(or I have to call a .findOne(something.getId())
method to have the complete persisted entity):
@RestController
@RequestMapping("/api")
@Transactional
public class SomethingResource {
private final SomethingRepository somethingRepository;
private final EntityManager em;
public SomethingResource(SomethingRepository somethingRepository, EntityManager em) {
this.somethingRepository = somethingRepository;
this.em = em;
}
@PostMapping("/somethings")
public Something createSomething(@RequestBody Something something) throws URISyntaxException {
Something result = somethingRepository.save(something);
em.refresh(result);
return result;
}
}
通过这种解决方法,我得到了预期的保存内容(使用正确的 JSON):
With this workaround, I've the expected saved entith (with a correct JSON):
{
"id": 4,
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1,
"shape": "Rectangle",
"color": "Red",
"dimension": 50
}
}
是否有自动方法/注释,使用 JPA 或 Spring 或 Hibernate,以便完整"?持久化实体?
Is there an automatic method/annotation, with JPA or Spring or Hibernate, in order to have the "complete" persisted entity?
我想避免在每个 REST 或服务类中声明 EntityManager
,或者我想避免每次我想要调用 .findOne(Long)
方法新刷新的持久化实体.
I would like to avoid to declare the EntityManager
in every REST or Service class, or I want avoid to call the .findOne(Long)
method everytime I want the new refreshed persisted entity.
推荐答案
不是在每个资源中定义EntityManager
,你可以通过创建一个<强>自定义 JpaRepository.参考
Instead of defining EntityManager
in each of your resource, you can define it once by creating a Custom JpaRepository. Reference
然后直接在每个存储库中使用 EntityManager
的 refresh
.
Then use the refresh
of your EntityManager
in each of your repository directly.
参考下面的例子:
自定义存储库接口
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import java.io.Serializable;
@NoRepositoryBean
public interface CustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
void refresh(T t);
}
自定义存储库实现
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.io.Serializable;
public class CustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements CustomRepository<T, ID> {
private final EntityManager entityManager;
public CustomRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
}
@Override
@Transactional
public void refresh(T t) {
entityManager.refresh(t);
}
}
在 Spring Boot 应用程序类中启用自定义 JPARepository
@SpringBootApplication
@EnableJpaRepositories (repositoryBaseClass = CustomRepositoryImpl.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
你的东西存储库
public interface SomethingRepository extends CustomRepository<Something, Long> {
}
直接在SomethingResource中使用Refresh(假设Something是一个实体)
Use Refresh directly in SomethingResource (Assuming Something is an Entity)
@RestController
@RequestMapping("/api")
@Transactional
public class SomethingResource {
private final SomethingRepository somethingRepository;
public SomethingResource(SomethingRepository somethingRepository) {
this.somethingRepository = somethingRepository;
}
@PostMapping("/somethings")
public Something createSomething(@RequestBody Something something) throws URISyntaxException {
Something result = somethingRepository.save(something);
somethingRepository.refresh(result);
return result;
}
}
这篇关于保存后刷新并获取实体(JPA/Spring Data/Hibernate)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!