我可以将文件上传到数据库(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();
}
}
答案 0 :(得分:3)
您想要使用
em.merge(entity);
而不是
em.persist(entity);
persist()直接存储和实体。 merge()将尝试更新当前实体。如果它不存在,它将存储它。
如果这不起作用,您应该向我们展示您的实体代码。 IIRC正确地在@Id列上完成合并。
<强>更新强>
您始终在创建新实体并保存该实体。要使合并工作,您应首先查找现有数据(如果已存在)。
在您的实体上创建@NamedQuery(必须将其包装在@NamedQueries中)。在你的dao上创建一个查找现有的文件方法。更新该实体,然后合并以进行保存。