覆盖数据库中的资源

时间:2013-01-08 21:22:04

标签: java mysql jpa

我可以将文件上传到数据库(mysql)。 当我尝试再次上传同一个文件时,我得到了:

” ... 内部异常:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键'filename'的重复条目'gg.txt' 错误代码:1062 调用:INSERT INTO RESOURCE(filename,override,product_id)VALUES(?,?,?)     bind => [gg.txt,false,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 个答案:

答案 0 :(得分:3)

您想要使用

em.merge(entity);

而不是

em.persist(entity);

persist()直接存储和实体。 merge()将尝试更新当前实体。如果它不存在,它将存储它。

如果这不起作用,您应该向我们展示您的实体代码。 IIRC正确地在@Id列上完成合并。

<强>更新

您始终在创建新实体并保存该实体。要使合并工作,您应首先查找现有数据(如果已存在)。

在您的实体上创建@NamedQuery(必须将其包装在@NamedQueries中)。在你的dao上创建一个查找现有的文件方法。更新该实体,然后合并以进行保存。