これらの2つの単純なエンティティSomething
とProperty
があります。 Something
エンティティは、Property
と多対1の関係があるため、新しいSomething
行を作成するときに、既存の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
(春)です:
@SuppressWarnings("unused")
@Repository
public interface SomethingRepository extends JpaRepository<Something,Long> {
}
RESTコントローラとJSONを使用して、新しい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はデータベースの既存の行です):
{
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1
}
}
問題は、次のとおりです。メソッド.save(something)
の後、変数result
には永続化されたエンティティが含まれますが、フィールドproperty
のフィールドがないと、検証されます(これらはnull
です)。
出力JSON:
{
"id": 1,
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1,
"shape": null,
"color": null,
"dimension": null
}
}
保存操作後に検証/返却されることを期待しています。
これを回避するには、RESTコントローラーでEntityManager
を挿入/宣言し、メソッドEntityManager.refresh(something)
を呼び出す(または.findOne(something.getId())
メソッドを呼び出す必要がある)完全に永続化されたエンティティを持つ):
@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を使用して)予想される節約量全体が得られました。
{
"id": 4,
"name": "MyName",
"owner": "MySelf",
"property": {
"id": 1,
"shape": "Rectangle",
"color": "Red",
"dimension": 50
}
}
「完全な」永続エンティティを持つために、JPA、Spring、またはHibernateを使用した自動メソッド/アノテーションはありますか?
すべてのRESTまたはServiceクラスでEntityManagerを宣言することを避けたい、または新しい更新された永続化エンティティが必要になるたびに.findOne(Long)メソッドを呼び出さないようにしたい。
Andreaどうもありがとう
Spring Boot JpaRepository:
変更するクエリが永続化コンテキストに含まれるエンティティを変更すると、このコンテキストは古くなります。
最新のレコードでデータベースからエンティティをフェッチするため。
@Modifying(clearAutomatically = true)を使用します
@ModifyingアノテーションにはclearAutomatically属性があり、変更クエリを実行した後に、基になる永続化コンテキストをクリアする必要があるかどうかを定義します。
例:
@Modifying(clearAutomatically = true)
@Query("UPDATE NetworkEntity n SET n.network_status = :network_status WHERE n.network_id = :network_id")
int expireNetwork(@Param("network_id") Integer network_id, @Param("network_status") String network_status);