为什么Hibernate与H2的行为与使用MySQL的Hibernate不同?
我们使用 Hibernate 作为ORM。在我们的实时系统中,我们使用 MySQL 数据库和 LiquiBase 来维护数据库模式。 在我们的测试系统中,我们直接使用内存 H2数据库(不需要Liquibase)。
在我们的实时系统中,当我们更新关系的一侧(通常是包含外键的那一方)时,实体之间的双向关系会被hibernate自动更新。 在我们的测试环境中,这种魔力已经消失,我们不得不明确双方更新关系。
我们不明白,为什么我们的测试环境表现得如此不同。它只是MySQL + Liquibase与H2之间的区别吗?
我知道,most documentation for hibernate / JPA表示对象之间的关系仍然需要手动维护,即使在使用休眠时也是如此。 但由于它在我们的实时系统中有效,我们希望为我们的测试复制相同的行为。
我们已经尝试添加更多注释,以便为H2 DB提供有关架构及其依赖关系的更多信息,但这并没有帮助。
那么,我们有什么办法可以在H2中强制进行这些自动更新吗?
我们拥有可以拥有CompanyPositions的用户。此关系建模为单独的类:UserCompanyPosition。
以下是我尝试删除相关部分的一些代码。首先是两个实体和关系类。然后是一种更新关系和小测试方法的方法。
请告诉我哪些其他信息有助于回答这个问题。
User.java:
@Entity
@Cacheable
@org.hibernate.annotations.Cache(
usage = CacheConcurrencyStrategy.READ_WRITE, region = "our_region")
@Table(name = "users")
public class User extends Model {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "user") // the relevant field
private List<UserCompanyPosition> userCompanyPositions = new ArrayList<>();
// ... default getters & setters, simple constructor
}
CompanyPosition.java:
@Entity
@Cacheable
@org.hibernate.annotations.Cache(
usage = CacheConcurrencyStrategy.READ_WRITE, region = "our_region")
@Table(name = "company_positions")
public class CompanyPosition extends Model {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "companyPosition") // relevant field
private List<UserCompanyPosition> userCompanyPositions = new ArrayList<>();
// ... default getters & setters, simple constructor
}
UserCompanyPosition.java:
@Entity
@Cacheable
@org.hibernate.annotations.Cache(
usage = CacheConcurrencyStrategy.READ_WRITE, region = "our_region")
@Table(
name = "users_company_positions",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"company_position_id", "user_id"})})
public class UserCompanyPosition extends Model {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_position_id", nullable = false)
private CompanyPosition companyPosition;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
public UserCompanyPosition(User user, CompanyPosition companyPosition) {
this.user = user;
this.companyPosition = companyPosition;
}
//... default getters & setters
}
UserCompanyPositionController.java中的创建方法:
protected Model createUserCompanyPosition(User user, CompanyPosition companyPosition) {
UserCompanyPosition userCompanyPosition = new UserCompanyPosition(user, companyPosition);
hibernateSession.saveOrUpdate(userCompanyPosition);
userCompanyPosition.notifyClientAboutChange(hibernateSession);
// These both lines are not necessary in the live system.
// But without them, the test below fails:
user.getUserCompanyPositions().add(userCompanyPosition);
companyPosition.getUserCompanyPositions().add(userCompanyPosition);
return userCompanyPosition;
}
测试:
public void testCreateObject() throws Exception {
controller.createUserCompanyPosition(existingUser, existingCompanyPosition);
assertEquals(companyPosition.getUserCompanyPositions().get(0),
user.getUserCompanyPositions().get(0));
// the queried collection user.getCompanyPositions() is empty,
// when we don't explicitly add the references
}
答案 0 :(得分:0)
也许尝试在应用程序属性中设置此属性以进行测试evnironment。
spring.jpa.hibernate.ddl-自动=创建降