如何覆盖单元测试的insertable=false



我是我们应用程序中另一个系统的访客,我不想做任何具有大规模影响的更改。

我正在从头开始写一个单元测试,因为上一位作者没有打扰。(Grumble。(我正试图插入一行来用JPA/hibernate测试我的查询,很惊讶我得到了以下错误:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_14316 table: OPTIONVALUE column: OPTION_INDEX
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:989)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:293)
at com.sun.proxy.$Proxy109.flush(Unknown Source)

特别是当我知道我已经设置了值,因为我必须为它写一个setter。然后,在其中一个对象上,我发现了以下定义(我必须查找(:

public static final String OPTION_VALUE_POSITION_COLUMN = "option_index";
@Column(name = OPTION_VALUE_POSITION_COLUMN, insertable = false, updatable = false, nullable = false)
private int position;

所以这就解释了为什么我在那个列上仍然为null。

我对删除insertable没有太大的问题,因为它不是自动生成的,所以如果你正在插入一个记录,为什么不想包括它呢?这显然在系统中从未发生过。可更新会保护它。但如果我不想的话,我真的不想。

所以,我的问题是,有没有一种方法可以在单元测试中覆盖它。我试着在谷歌上搜索了一些东西,但这方面的措辞有点问题,我什么也没找到。

通常,您可以在测试包中重新定义任何类,并且它将被加载,而不是主类,因为它具有更高的优先级。类加载路径通常按以下顺序排列优先级:

  1. 测试类(如果正在运行测试(
  2. 测试资源(如果正在运行测试(
  3. 主要类别
  4. 主要资源
  5. 测试依赖关系jar(如果正在运行测试(
  6. 主要依赖关系jar

你可以像这样检查:

// I have yet to run into a custom ClassLoader that does not extend URLClassLoader
URLClassLoader urls = (URLClassLoader) getClass().getClassLoader();
for (URL url : urls.getURLs()) {
System.out.println(url);
}

不过,这里有点问题。Hibernate的ClassLoader可能(也可能不(从Test中读取重写的类,除非您在测试资源中有配置文件persistence.xmlorm.xml或其他文件。情况可能是这样,也可能不是这样,但如果您需要在测试中有一个单独的配置,则它必须列出需要扫描的所有类。您不能依赖<exclude-unlisted-classes>false</exclude-unlisted-classes>条目,因为Hibernate的扫描程序具有深度感知功能,并且在类路径层次结构中的深度不会超过它找到配置XML的级别。

我不知道这是否是最好的解决方案,但在某些情况下,它可能是一个合法的解决方案。

在以下情况下,我使用原始查询插入/更新我的实体:

Query query = entityManager.createNativeQuery("insert into MY_TABLE " + 
"(ID, NAME) values (1, 'user1')");
query.executeUpdate();

最新更新