Thom
Thom

Reputation: 15052

How to override insertable=false for a unit test

I am something of a guest on another system in our application and I don't want to make any kind of a change with large scale ramifications.

I am writing a unit test from scratch, since the previous author didn't bother. (Grumble.) I am attempting to insert a row to test my query with JPA/hibernate and was surprised that I got the following error:

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)

Especially when I knew that I had set the value because I had to write a setter for it. Then, on one of the objects, I found the following definition (which I had to look up):

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;

So that explains why I'm still getting null on that column.

I don't have a HUGE problem with removing insertable because it's not auto generated, so why would you NOT want to include it if you're inserting a record, which evidently never happens inside the system. And updatable will protect it. But I really don't want to if I don't have to.

So, my question is, is there a way to override this just for the unit test. I tried googling a couple of things, but phrasing for this is a bit a problem and I didn't find anything.

Upvotes: 3

Views: 931

Answers (2)

ihebiheb
ihebiheb

Reputation: 5183

I dont know if it is the best solution, but it can be a legit workaround in some cases.

I used raw queries to insert/update my entities in these cases :

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

Upvotes: 0

coladict
coladict

Reputation: 5095

Normally you can redefine any class in the Test packages, and it will be loaded instead of the main class, because it has higher priority. Classloading paths are typically prioritized in this order:

  1. Test Classes (if running test)
  2. Test Resources (if running test)
  3. Main Classes
  4. Main Resources
  5. Test dependency jars (if running test)
  6. Main dependency jars

You can check it like:

// 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);
}

Here's a bit of a problem, though. Hibernate's ClassLoader might (or might not) read the overridden class from Test, unless you have your configuration file persistence.xml, orm.xml or whatever in the Test Resources. This may or may not be the case, but if you need to have a separate configuration in the test, then it must list all the classes that need to be scanned. You cannot rely on the <exclude-unlisted-classes>false</exclude-unlisted-classes> entry, because Hibernate's scanner is depth-aware and does not go deeper in the Class-Path hierarchy than the level at which it found the configuration XML.

Upvotes: 1

Related Questions