2017-11-07 15 views
0

を使用してセーブ/アップデート中のエンティティリフレッシュSpringブートでSpring Data JPAを使用しています。SpringデータJPA

エンティティがSpring Data Jpaリポジトリを使用してデータベースに保存された後、エンティティ全体が取得されません。つまり、save()に渡した値だけを取得します。

私はgoogle/SOをチェックしてから、entityManager.refresh(organization)を追加しました。今私はエンティティ全体とマッピングされたエンティティを取得しています。

エンタープライズエンティティ:

@Entity 
@Table(name = "enterprise") 
public class Enterprise extends BaseEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "enterprise_id") 
    private Long enterpriseId; 
    @Column(name = "enterprise_external_name", length = 150, unique = true) 
    @NotNull 
    private String enterpriseExternalName; 
    @Column(name = "enterprise_internal_name", length = 150, unique = true) 
    @NotNull 
    private String enterpriseInternalName; 
    @OneToMany(mappedBy = "enterprise") 
    @JsonIgnoreProperties(allowSetters = true, value = { "enterprise" }) 
    private Set<Organization> organizations; 
    //getter and setters 
} 

組織エンティティ:

@Entity 
@Table(name = "organization") 
public class Organization extends BaseEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "organization_id") 
    private Long organizationId; 
    @Column(name = "organization_name", length = 150, unique = true) 
    @NotBlank(message = "OrganizationName can't be empty !") 
    private String organizationName; 
    @ManyToOne 
    @JoinTable(name = "enterprise_organization", joinColumns = { 
      @JoinColumn(name = "organization_id") }, inverseJoinColumns = { @JoinColumn(name = "enterprise_id") }) 
    @JsonIgnoreProperties(allowSetters = true, value = { "organizations" }) 
    private Enterprise enterprise; 
    //getters and setters 
} 

コントローラクラス:

@PostMapping 
public ResponseEntity<ValidationResponse> addOrganization(@Valid @RequestBody Organization organization) 
{ 
    ValidationResponse response = new ValidationResponse(); 
    response.setMessage(organizationService.addOrganization(organization)); 

    return new ResponseEntity<ValidationResponse>(response, HttpStatus.CREATED); 
} 

サービスクラス:

@Service 
@Transactional(propagation = Propagation.REQUIRED) 
public class OrganizationServiceImpl implements OrganizationService { 
    @PersistenceContext 
    private EntityManager entityManager; 
    @Autowired 
    private OrganizationRepository organizationRepository;  
    public Organization addOrganization(Organization organization) { 
     organization.setCreatedDate(Calendar.getInstance()); 
     organizationRepository.save(organization); 
     entityManager.refresh(organization); 
     return organization; 
    } 
} 

リポジトリ:

@Repository 
public interface OrganizationRepository extends JpaRepository<Organization, Long> { 
} 

リクエストボディ:

{ 
    "success": true, 
    "message": { 
     "createdBy": 0, 
     "updatedBy": 0, 
     "createdDate": 1510140158654, 
     "updatedDate": null, 
     "organizationId": 14, 
     "organizationName": "org5", 
     "enterprise": { 
      "createdBy": 0, 
      "updatedBy": 0, 
      "createdDate": null, 
      "updatedDate": null, 
      "enterpriseId": 2,    
      "enterpriseName": null, 
      "active": true 
     }, 
     "active": true 
    }, 
    "errors": null 
} 

しかし、私が見つけた問題:

{ 
    "organizationName":"org5", 
    "enterprise":{ 
     "enterpriseId":2 
    } 
} 

レスポンス私はentityManager.refresh(組織)が含まれていない場合再びそのデータベースに当たってデータを選択することでした。より多くのマッピングがある場合や、entityManager.refresh()を追加する必要があるすべてのサービスクラスのメソッドでも、パフォーマンスの問題になります。 これは、保存/更新後にエンティティを更新する唯一の方法ですか?または、設定などを追加することでこれを回避できますか?提案してください。

ありがとうございました。

答えて

0

「組織」オブジェクトはどこに作成されていますか。 addOrganization()メソッド内で作成または取得してから保存すると、うまくいくはずです。ベスト・プラクティスとして、サービス・レイヤーは、OpenSessionInViewFilterを使用してドメインをコントローラーとビューに渡さない限り、コントローラーではなく、Domainオブジェクトを処理する必要があります。

+0

Controllerクラスを追加して質問を更新しました。チェックしてください。参考までに、REST APIのみを実装しています。 – Krish

0

あなたの問題は、あなたのサービスでこの行にあると思います。

organizationRepository.save(organization); 

パラメータオブジェクトを返す代わりに、saveメソッドから戻り値を返します。

public Organization addOrganization(Organization organization) { 
    organization.setCreatedDate(Calendar.getInstance()); 
    return organizationRepository.save(organization);; 
} 

EDIT:

私の答えは全く役に立たない質問を再読した後。おそらく、エンティティ全体をsaveメソッドに提供しなければならないか、単一のフィールドを更新してリポジトリから取得し、エンティティのフィールドを設定する必要があるかもしれません。トランザクション・ライト・バックは変更を永続化するため、保存する必要はありません。

+0

@ c-weberつまり、save()から返されたIdを使ってエンティティ全体を取得する必要がありますか? – Krish

+0

私の答えを編集して、私が意味することをより明確にします。 saveメソッドは、エンティティ全体を返すIDだけでなく、 –

+0

@ c-weber私はすでにそれを試みましたが、うまくいきませんでした。組織とsave()からの戻り値はどちらも同じです。 save()はIDフィールドを更新するだけで、それ以上は更新されません。 – Krish

関連する問題