2013-01-08 63 views
1

我可以將文件上傳到數據庫(mysql)中。 當我嘗試再次上傳同一文件中,我得到:覆蓋數據庫中的資源

」 ...... 內部異常:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:重複的項目‘gg.txt’關鍵‘文件名’ 錯誤編號:1062 電話:INSERT INTO RESOURCE(文件名,覆蓋的product_id)VALUES 綁定=> [gg.txt,假,1] ......」

現在我想(,,???)啓用覆蓋上傳的文件,當我有標誌設置爲true。

我已經寫的類,它實現Upload.StartedListener,Upload.ProgressListener,Upload.Receiver,Upload.FinishedListener,Upload.SucceededListener和Upload.FailedListener

下面的代碼片段

@Override 
public void uploadStarted(StartedEvent event) { 
    progress.setValue(0f); 
    progress.setVisible(true); 
    cancelButton.setVisible(true); 
    uploadField.setVisible(false); 
} 

@Override 
public void updateProgress(long readBytes, long contentLength) { 
    progress.setValue(new Float(readBytes/(float)contentLength)); 
} 

@Override 
public OutputStream receiveUpload(String filename, String mimeType) { 
    OutputStream outputStream = null; 
    try { 
     String dir = resourceDao.getAbsoluteDir(product); 
     // ensures that the dir exists 
     new File(dir).mkdirs(); 
     uploadedFile = new File(dir + filename); 
     if (!uploadedFile.exists()) { 
      uploadedFile.createNewFile(); 
     } 
     outputStream = new FileOutputStream(uploadedFile); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return outputStream; 
} 

@Override 
public void uploadSucceeded(SucceededEvent event) { 
    checkArgument(product != null, "Product is null."); 
    String filename = uploadedFile.getName(); 
    Resource res = new Resource(); 
    res.setFilename(filename); 
    res.setProduct(product); 
    product.getResources().add(res); 
    productDao.save(product); 
    eventBus.post(new ResourceAddedEvent(res)); 
    uploadedFile = null; 
} 

@Override 
public void uploadFailed(FailedEvent event) { 
    if (uploadedFile != null && uploadedFile.exists()) { 
     uploadedFile.delete(); 
    } 
    uploadedFile = null;   
} 

燦你給我一些建議,如何啓用覆蓋上傳的文件?

保存resourceDao的方法:

@Override 
public void save(Resource entity) { 
    em.getTransaction().begin(); 
    em.persist(entity); 
    em.getTransaction().commit(); 
} 

EM - EntityManager的

資源表

@Entity(name = Resource.ENTITY_NAME) 
public class Resource { 

public static final String ENTITY_NAME = "resource"; 

public static final String COLUMN_ID = "id"; 

public static final String COLUMN_PRODUCT_ID = "product_id"; 

public static final String COLUMN_FILENAME = "filename"; 

public static final String COLUMN_OVERRIDE = "override"; 

public static final String ATTRIBUTE_ID = COLUMN_ID; 

public static final String ATTRIBUTE_FILENAME = COLUMN_FILENAME; 

public static final String ATTRIBUTE_PRODUCT = "product"; 

public static final String ATTRIBUTE_OVERRIDE = "override"; 


// User identifier. 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = COLUMN_ID) 
private int id; 


//Product that the resource belongs to. 
@ManyToOne 
@JoinColumn(name = COLUMN_PRODUCT_ID, nullable = false) 
private Product product; 

//Path for the file. 
@Column(name = COLUMN_FILENAME, nullable = false, unique = true) 
private String filename; 

//Flag that indicates if the resource can be override. 
@Column(name = COLUMN_OVERRIDE, nullable = false) 
private boolean isOverride; 

public static String getLabel(String attribute) { 
    return Messages.getLabel("product_resource." + attribute); //$NON-NLS-1$ 
} 

//...getters and setters... 

@Override 
public int hashCode() { 
    return Objects.hash(id, filename, getProduct()); 
} 

@Override 
public boolean equals(Object obj) { 
    if (obj == this) { 
     return true; 
    } 
    if (obj instanceof Resource) { 
     Resource resource = (Resource)obj; 
     if (resource.id != this.id) { 
      return false; 
     } 
     // if the id match - check the following attributes 
     return Objects.equals(filename, resource.filename) && // 
       Objects.equals(getProduct(), resource.getProduct()); 
    } 
    return false; 
} 

@Override 
public String toString() { 
    return com.google.common.base.Objects.toStringHelper(this) // 
      .add(ATTRIBUTE_ID, id) // 
      .add(ATTRIBUTE_FILENAME, filename) // 
      .toString(); 
} 
} 
+1

我沒有看到任何代碼與MySQL交互。 –

+0

更改productDao的保存方法。閱讀:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html – Leonidos

+0

productDao?不是resourceDao?現在我的保存方法如下所示:@Override public void save(Resource entity){em_getTransaction()。begin(); em.persist(entity); em.getTransaction()。commit(); } 是否有可能使用實體管理器來解決它? – akuzma

回答

3

你想用

em.merge(entity); 

,而不是

em.persist(entity); 

persist()直接存儲和實體。 A merge()將嘗試更新當前實體。如果它不存在,它將存儲它。

如果這不起作用,你應該告訴我們你的實體代碼。 IIRC正確地在@Id列進行合併。

更新

你總是創建一個新的實體,並保存一個。爲了合併工作,如果它已經存在,應該首先在現有數據中進行查找。

在您的實體上創建一個@NamedQuery(它必須包裝在@NamedQueries中)。在您的dao上創建一個查找現有文件方法。更新該實體,然後合併保存。

+0

不幸合併不能正常工作 – akuzma

+0

@akuzma剛剛發佈了另一個更新。 –