2016-08-18 1 views
1

を永続化されない:スプリングデータJPAエンティティ変化は、Iのような定義された(/休止状態とMySQL wはJPAを使用して)スプリング・データ・エンティティを有する

@Entity 
@Table(name = "dataset") 
public class Dataset { 

    @Id 
    @GenericGenerator(name = "generator", strategy = "increment") 
    @GeneratedValue(generator = "generator") 
    private Long id; 
    @Column(name = "name", nullable = false) 
    private String name; 
    @Column(name = "guid", nullable = false) 
    private String guid; 
    @Column(name = "size", nullable = false) 
    private Long size; 
    @Column(name = "create_time", nullable = false) 
    private Date createTime; 
    @OneToOne(optional = false) 
    @JoinColumn(name = "created_by") 
    private User createdBy; 
    @Column(name = "active", nullable = false) 
    private boolean active; 
    @Column(name = "orig_source", nullable = false) 
    private String origSource; 
    @Column(name = "orig_source_type", nullable = false) 
    private String origSourceType; 
    @Column(name = "orig_source_org", nullable = false) 
    private String origSourceOrg; 
    @Column(name = "uri", nullable = false) 
    private String uri; 
    @Column(name = "mimetype", nullable = false) 
    private String mimetype; 
    @Column(name = "registration_state", nullable = false) 
    private int registrationState; 
    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @JoinColumn(name = "dataset_id") 
    @JsonManagedReference 
    private List<DatasetFile> datasetFiles; 

私はこのエンティティの以下のリポジトリを有する:

public interface DatasetRepo extends JpaRepository<Dataset, Long> { 

    @Query("SELECT CASE WHEN COUNT(p) > 0 THEN 'true' ELSE 'false' END FROM Dataset p WHERE p.uri = ?1 and p.registrationState>0") 
    public Boolean existsByURI(String location); 

    @Query("SELECT a FROM Dataset a LEFT JOIN FETCH a.datasetFiles c where a.registrationState>0") 
    public List<Dataset> getAll(Pageable pageable); 

    @Query("SELECT a FROM Dataset a LEFT JOIN FETCH a.datasetFiles c WHERE a.registrationState>0") 
    public List<Dataset> findAll(); 

    @Query("SELECT a FROM Dataset a LEFT JOIN FETCH a.datasetFiles c where a.guid= ?1") 
    public Dataset findByGuid(String guid); 
} 

Now - コントローラでは、データセットを取得してその属性の1つを更新していますが、その属性の変更がDBにフラッシュされることを期待していますが、それは決してありません。

@RequestMapping(value = "/storeDataset", method = RequestMethod.GET) 
    public @ResponseBody 
    WebServiceReturn storeDataset(
      @RequestParam(value = "dsGUID", required = true) String datasetGUID, 
      @RequestParam(value = "stType", required = true) String stType) { 
     WebServiceReturn wsr = null; 
     logger.info("stType: '" + stType + "'"); 
     if (!stType.equals("MongoDB") && !stType.equals("Hive") && !stType.equals("HDFS")) { 
      wsr = getFatalWebServiceReturn("Invalid Storage type '" + stType + "'"); 
     } else if (stType.equals("MongoDB")) { 
      /* Here is where I'm reading entity from Repository */ 
      Dataset dataset = datasetRepo.findByGuid(datasetGUID); 
      if (dataset != null) { 
       MongoLoader mongoLoader = new MongoLoader(); 
       boolean success = mongoLoader.loadMongoDB(dataset); 
       logger.info("Success: " + success); 
       if (success) { 
        /* Here is where I update entity attribute value, this is never flushed to DB */ 
        dataset.setRegistrationState(1); 
       } 
       wsr = getWebServiceReturn(success ? 0 : -1, "Successfully loaded dataset files into " + stType + " storage", "Failed to load dataset files into " + stType + " storage"); 
      } 

     } 
     return wsr; 
    } 

はあなたが@Transactionalで要求マッピングの方法に注釈を付ける必要がある

+0

私は、Springのデータクエリから返ってくるエンティティが管理されていないことをかなり確信しています(少なくとも私が思っている通りではありません)。 'entityManager.contains(dataset)'を実行すると 'false'が返されます。私は変更をマージする 'datasetRepo.save(dataset)'を実行することによって変更を維持することができますが、誰かがなぜクエリから返ってくるエンティティが管理されていないのか、 ? –

+1

メソッド 'storeDataset'に' @ Transactional'というアノテーションを付けてみてください。 – Pau

+0

hibernateクエリログを有効にして、何が起こっているのかを確認してください。 –

答えて

0

ありがとうございます。

なぜですか?メモリ内のオブジェクトを変更する場合は、データベース内のオブジェクトを透過的に更新する必要があります。アクティブなトランザクション内で行う必要があります。

JPA(spring-dataは、JPAを使用しています)を使用していることを忘れないでください。エンティティがmanaged stateになるようにするには、アクティブなトランザクションが必要です。

参照:

透明更新エンティティオブジェクトが データベース(かかわらず道)から取得されると、それは単に内側からメモリ に修飾することができますアクティブな取引:

Employee employee = em.find(Employee.class, 1); 

em.getTransaction().begin(); 
employee.setNickname("Joe the Plumber"); 
em.getTransaction().commit(); 
関連する問題