В Spring MVC приложении я имею упрощенную модель следующего вида. Класс User, у которого есть список файлов:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private int id;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY, mappedBy = "owner")
private Set<StoredFile> storedFiles = new HashSet<>();
//.........//
}
Файлы с одинаковым именем не должны добавляться в базу. Класс файл:
@Entity
@Table(name = "stored_files")
public class StoredFile {
@Id
@GeneratedValue
private int id;
@Column(unique = false)
private String name;
private LocalDateTime time;
@ManyToOne
private User owner;
private boolean shared;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof StoredFile)) return false;
StoredFile that = (StoredFile) o;
return getName().equals(that.getName());
}
@Override
public int hashCode() {
int hash = Objects.hash(getName());
return hash;
}
}
Я добавляю первый файл user.getStoredFiles().add(new StoredFile(...))
,
Обновляю юзера, CascadeType.MERGE обновляет и коллекцию entityManger.merge(user)
Файл появился в базе. Добавляю так же второй файл, но в базу попадает снова первый файл и второй:
Если добавить третий файл, то их в базе будет уже 6. В списке storedFiles
Элементы не дублируются, т.е. это уже происходит в недрах метода merge(). В чём может быть проблема? Пробовал ставить на имени @Column(unique=true)
- в postgresql это срабатывает, записываются только новые файлы, на старые вылетает эксепшн, а вот в mysql после эксепшена файлы вообще не записываются в базу.
UPDATE:
добавление файла в методе контроллера:
@PostMapping("/savefile")
@ResponseBody
public void saveFile(@RequestParam(name = "file")MultipartFile file, @RequestParam String shared, HttpSession session){
User user = (User) session.getAttribute("user");
String name = file.getOriginalFilename();
try {
FileUtils.writeByteArrayToFile(new File(GeneralSettings.STORED_FILES_PATH + user.getLogin() + "/" + name), file.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
user.getStoredFiles().add(new StoredFile(name, LocalDateTime.now(), user, shared.equals("1")));
userDAO.updateUser(user);
}
UserDAO:
@Repository("user_dao")
@Transactional
public class UserDAO {
@PersistenceContext
private EntityManager em;
@Transactional
public void updateUser(User user) {
em.merge(user);
}
}
При втором и последующем merge User вы мерджите старое значение с пустыми id в StoredFile.
Соответственно вам нужно:
Или
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть программа, которая работает, но числа long очень долго думает, а иногда и не все выписываетУсловия : программа должна работать пока не вводится...
Смысл в том, что в зависимости от получаемых методом GET параметрах сервлетом необходимо выполнить тот или иной метод - getN1FromDB, getN2FromDB и тд
Я хотел бы использовать эту красивую SVG-анимацию, размещенную на CodePen, но я не могу понять, как запустить или перезапустить анимацию: