2016-08-18 47 views
1

我具有彈簧數據實體(使用JPA瓦特/休眠和MySQL)定義爲這樣:大春數據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); 
} 

現在 - 在一個控制器中,我正在讀取一個數據集,更新其中一個屬性,我期望將該屬性更改刷新到數據庫,但它從來沒有。

@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; 
    } 

謝謝

+0

所以 - 我非常確定從Spring數據查詢返回的實體不受管理(至少不是我認爲它的方式)。如果我運行'entityManager.contains(dataset)',返回'false'。我可以通過運行'datasetRepo.save(dataset)'來合併更改,但可以通過運行'datasetRepo.save(dataset)'來獲得更改,但是有人可以告訴我爲什麼從查詢中返回的實體不受管理,我如何才能管理它? –

+1

嘗試將您的方法'storeDataset'註釋爲'@ Transactional' – Pau

+0

您應該打開hibernate查詢日誌以查看封面上發生了什麼。 –

回答

0

你需要註釋的請求映射的方法,採用@Transactional

爲什麼?如果要修改內存中的對象,然後在數據庫中透明地更新對象,則需要在活動事務中執行該操作。

不要忘記你正在使用JPA(spring-data正在使用JPA),如果你想要你的實體將在managed state你需要一個活躍的交易。

參見:

透明更新一旦實體對象從 數據庫(不管哪一種方式),它可以簡單地在存儲器 內部的改性從中檢索活躍交易:

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

em.getTransaction().begin(); 
employee.setNickname("Joe the Plumber"); 
em.getTransaction().commit();