У меня есть 2 Entity
. Product
и User
:
@Entity
@Table(name="users")
public class User {
@Id @GeneratedValue
@Column(name="id")
private int id;
@Column(name="login")
private String login;
@Column(name="email")
private String email;
@Column(name="password")
private String password;
@Column(name="mobilePhone")
private String mobilePhone;
@Column(name="firstName")
private String firstName;
@Column(name="secondName")
private String secondName;
@Column(name="address")
private String address;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "customer")
private List<Product> cart;
//гетери и сетери
}
Product:
@Entity
@Table(name = "products")
public class Product {
@Id @GeneratedValue
@Column(name="id")
private int product_id;
@Column(name="name")
private String name;
@Column(name="descr")
private String descr;
@Column(name="price")
private int price;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User customer;
//гетери сетери
}
И есть класс которий тестит:
public class ProductServiceTest extends AbstractServiceTest{
@Autowired
private ProductService productService;
@Autowired
private UserService userService;
@Test
public void runTest(){
User user = userService.get("AnotherLogin").get(0);
Product product = new Product();
product.setName("Test");
product.setDescr("Test");
product.setPrice(10101010);
user.getCart().add(product);
userService.update(user);
}
}
Если я хочу получить список Product
, которие принадлежат User
, все работает нормально. Но когда я запускаю етот тест, то обьект product
просто пропадает, и в бд не попадает, тоже и з удалением, апдейтом.
[UPDATE] Git репозиторий: https://github.com/OlegHudyma/Medical_WebSite
Классы-сущности:
@Entity
@Table(name="users")
public class User {
@Id @GeneratedValue
@Column(name="id")
private int id;
@OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "customer",
orphanRemoval = true //для удаления элемента в removeTest
)
private List<Product> cart;
//гетеры, сетеры, другие поля
}
@Entity
@Table(name = "products")
public class Product {
@Id @GeneratedValue
@Column(name="id")
private int product_id;
@ManyToOne(fetch = FetchType.LAZY
//тут не нужно cascade, иначе будет рекурсивное удаление
//,cascade = CascadeType.ALL
)
@JoinColumn(name = "user_id")
private User customer;
//гетеры, сетеры, другие поля
}
Класс с тестом должен выглядеть примерно так:
public class ProductServiceTest extends AbstractServiceTest{
@Autowired
private SessionFactory sessionFactory;
@Test
public void addTest() {
Session currentSession = sessionFactory.openSession();
Transaction tx = null;
try {
tx = currentSession.beginTransaction();
User user = currentSession.createQuery("from User", User.class).getResultList().get(0);
Product product = new Product();
product.setName("Test3");
product.setCustomer(user);
//в рамках сессии добавили продукт
user.getCart().add(product);
//update не нужен, т.к. удаляем в hibernate транзакции
//currentSession.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
currentSession.close();
}
}
// Или так (то же самое, но выполняется внутри метода помеченного @Transactional)
// @Transactional
// public void addTest() {
// User user = currentSession.createQuery("from User", User.class).getResultList().get(0);
// Product product = new Product();
// product.setName("Test3");
//
// product.setCustomer(user);
// //в рамках сессии добавили продукт, по окончании метода сохранится в БД
// user.getCart().add(product);
// }
@Test
public void removeTest() {
Session currentSession = sessionFactory.openSession();
Transaction tx = null;
try {
tx = currentSession.beginTransaction();
User user = currentSession.createQuery("from User", User.class).getResultList().get(0);
//удаляем первый элемент
user.getCart().remove(0);
//update не нужен, т.к. удаляем в hibernate транзакции
//currentSession.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
currentSession.close();
}
}
// Или так (то же самое, но выполняется внутри метода помеченного @Transactional)
// @Transactional
// public void removeTest() {
// User user = currentSession.createQuery("from User", User.class).getResultList().get(0);
// Product product = new Product();
// product.setName("Test3");
//
// product.setCustomer(user);
// //в рамках сессии добавили продукт, по окончании метода сохранится в БД
// user.getCart().add(product);
// }
}
Как видете из этих 2-х тестов, все добавляется и удаляется с помощью cascade = CascadeType.ALL
. Почитайте как работает hibernate транзакции, и у Вас все будет получатся.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Не могу разобраться с итераторами, здесь он выводит просто подряд числа, как сделать так, чтобы выводились числа, которые стоят на нечетной...