【发布时间】:2015-05-17 14:59:02
【问题描述】:
这个问题类似于this one,但我的问题特别是Spring Boot的原生CrudRepository和JpaRepository,它们似乎没有refresh()方法。我正在保存一个新对象,其中包含现有子对象的 ID。该应用程序是 RESTful 的,插入的数据是来自客户端的 JSON。新记录已正确插入,但返回值中的子对象仍仅包含 ID。是否有等同于 refresh() 的 Spring Boot?我是否需要创建一个可以访问 EntityManager 的自定义存储库?
我应该补充一点,在插入后使用 findOne() 并不能解决问题。子对象仍然不完整。但是,当我在单独的 REST 调用中选择插入的记录时,该对象连同所有子对象都是完整的。
代码如下。如您所见,存储库和服务方法非常简单,以至于我不知道该怎么做。刷新看起来像是 Spring Boot 应该自动处理的事情。
注意:SO 评论表单正在从 CrudRepository 和一些参数中删除参数 返回类型。
Volume.java
@Entity
@JsonSerialize(using = VolumeSerializer.class)
public class Volume implements Protectable {
public static final int ATTACHED_STATE = 1;
public static final int DETACHED_STATE = 0;
public static final int SUSPENDED_STATE = -1;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@OneToOne
private VolumeType type;
private int size;
@OneToOne
private UserGroup userGroup;
@OneToOne
private Region region;
@OneToOne
private State state;
@OneToOne
private Status status;
@OneToOne
private Alarm alarmStatus;
private long createdDate;
@Column(columnDefinition = "bigint default 0")
private long lastModifiedDate = 0;
@Column(columnDefinition = "tinyint default 0")
private boolean monitoringEnabled = false;
@Column(columnDefinition = "tinyint default 0")
private boolean encrypted = false;
@OneToOne
private Snapshot snapshot;
@ManyToOne
private Instance instance;
/*
after this there are constructors, a long list of getters for the properties above
a static Builder class and @PrePersist and @PreUpdate methods
*/
...
VolumeRepository.java
/**
* For accessing Volume information
*/
public interface VolumeRepository extends CrudRepository {
List findByUserGroupId(long groupId);
}
VolumeService.java
@Transactional
public Iterable save(List volumes) {
return this.repository.save(volumes);
}
VolumeRouter.java
这是一个@RestController。
@RequestMapping(value="/volumes", method=RequestMethod.POST)
public Iterable create(@RequestBody List volumes) {
return this.service.save(volumes);
}
application.properties
(ddl-auto 设置用于开发)
# Datasource configuration
spring.datasource.url=****
spring.datasource.username=****
spring.datasource.password=****
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.time-between-eviction-runs-millis=34000
spring.datasource.min-evictable-idle-time-millis=55000
spring.datasource.min-idle=0
# Hibernate settings
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
VolumeServiceIT.java
JSON 字符串向您展示了客户的期望 能够发送到服务。 UserGroup 对象只包含 从客户端发送的 ID,但它应该是完整的用户组 目的。其他子对象也是如此。
@Test
public void createVolume() throws Exception {
String json = "[{" +
"\"name\": \"Test Volume\", " +
"\"size\": 24, " +
"\"monitoringEnabled\": true, " +
"\"encrypted\": true, " +
"\"state\": { \"id\": 1 }, " +
"\"userGroup\": { \"id\": 1 }, " +
"\"region\": { \"id\": 1 }, " +
"\"type\": { \"id\": 1 }" +
"}]";
mvc.perform(MockMvcRequestBuilders.post("/volumes")
.principal(token)
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].id", is(4)))
.andExpect(jsonPath("$[0].name", is("Test Volume")))
.andExpect(jsonPath("$[0].size", is(24)))
.andExpect(jsonPath("$[0].userGroup.id", is(1)))
.andExpect(jsonPath("$[0].userGroup.name", is("myGroup")))
.andExpect(jsonPath("$[0].userGroup.users", isEmptyOrNullString()))
.andExpect(jsonPath("$[0].type.id", is(1)))
.andExpect(jsonPath("$[0].type.value", is("SSD")))
.andExpect(jsonPath("$[0].region.id", is(1)))
.andExpect(jsonPath("$[0].region.value", is("us-west")))
.andExpect(jsonPath("$[0].state.id", is(1)))
.andExpect(jsonPath("$[0].state.value", is("on")))
.andExpect(jsonPath("$[0].status", isEmptyOrNullString()))
//.andExpect(jsonPath("$.createdDate", is(1425240151000L)))
.andExpect(jsonPath("$[0].monitoringEnabled", is(true)))
.andExpect(jsonPath("$[0].encrypted", is(true)));
}
【问题讨论】:
-
你是如何执行持久化的?你能发布正在使用的代码吗?
-
弗兰西斯科,感谢您的回复。我添加了相关代码。如您所见,它非常简单——只需在 CrudRepository 或 JpaRepository 上调用 save()。无论哪种方式都会出现问题。
标签: hibernate jpa spring-boot