Entity can still be found after being deleted - spring

I'm working with Spring Data Neo4j 4 and have the following user entity
#NodeEntity
public class User{
private Long id;
private String username;
//Getter, Setter
}
Using the Neo4j GraphRepository, i first create the user in one transaction and later delete him in a second transaction.
Working with the standalone Neo4j server on localhost:7474 i get no result when running "MATCH (n) return n" but when i run the findOne(Long id) method of the GraphRepository using the id of the User i just deleted, i get the user, i just deleted returned.
Is there some kind of behavior involved i don't understand?
Regards
Urr4
Edit:
My application class
#SpringBootApplication(scanBasePackages = {/.../})
#EnableNeo4jRepositories(basePackages = {/.../})
#EnableTransactionManagement
public class MyApplication extends Neo4jConfiguration {
public static void main(String[] args) {
SpringApplication.run(TSApplication.class, args);
}
#Override
#Bean
public Neo4jServer neo4jServer() {
return new RemoteServer(/.../);
}
#Override
#Bean
public SessionFactory getSessionFactory() {
return new SessionFactory("/.../);
}
}

After Michaels comment, i've googled a bit and added the following to my Controller:
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = RuntimeException.class)
Afterwards it worked - Thank you all :)

Related

Couldn't find PersistentEntity for type class when using #EnableMongoAuditing

I am getting "Couldn't find PersistentEntity for type class" error when I am using #EnableMongoAuditing features along with MongoRepository.
This happens when I save a document when collection isn't already present in database.
I tried whatever is mentioned in:
https://github.com/spring-projects/spring-boot/issues/12023
https://jira.spring.io/browse/DATAMONGO-1999
Spring boot mongodb auditing error
but nothing is working.
Mentioned things are:
Extend MongoConfig by AbstractMongoConfiguration and override all methods.
Here is my code which reproduced the same error:
MongoConfig class
#Configuration
public class MongoConfig extends AbstractMongoConfiguration {
#Value("${spring.data.mongodb.host}")
private String mongoHost;
#Value("${spring.data.mongodb.port}")
private String mongoPort;
#Value("${spring.data.mongodb.database}")
private String mongoDB;
#Override
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(new MongoClient(mongoHost + ":" + mongoPort), mongoDB);
}
#Override
public MongoClient mongoClient() {
return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
}
#Override
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoDbFactory());
}
#Override
public MappingMongoConverter mappingMongoConverter() {
return new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
}
#Override
protected String getDatabaseName() {
return mongoDB;
}
}
Person Collection class
#Document
public class Person {
#Id
private String id;
private String name;
#CreatedDate
private LocalDateTime createdAt;
#LastModifiedDate
private LocalDateTime lastModified;
// Getter Setters Constructors omitted for brevity
}
Main Application class
#EnableMongoAuditing
#EnableMongoRepositories ({"com.example.*", "org.apache.*"})
#SpringBootApplication
#ComponentScan({"com.example.*", "org.apache.*"})
public class DemoApplication implements CommandLineRunner {
#Autowired
PersonRepository personRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
Person p1 = new Person("1", "prakhar");
personRepository.save(p1);
}
}
Expected Result is Person entity should be saved in database.
Actual Result is "Couldn't find PersistentEntity for type class Person" error
Looks like you ran into https://github.com/spring-projects/spring-boot/issues/12023
Extending AbstractMongoConfiguration will switch off Spring Boot's auto-configuration of various Mongo components and also customises the base packages that are used to scan for mappings. I would recommend that you don't use it in Spring Boot.
Update
I managed to get the example running with the configuration as simple as
#Configuration
public class MongoConfig {
#Value("${spring.data.mongodb.host}")
private String mongoHost;
#Value("${spring.data.mongodb.port}")
private String mongoPort;
#Value("${spring.data.mongodb.database}")
private String mongoDB;
#Bean
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(new MongoClient(mongoHost + ":" + mongoPort), mongoDB);
}
#Bean
public MongoClient mongoClient() {
return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
}
}
and the app class
#EnableMongoAuditing
#SpringBootApplication
public class DemoApplication implements CommandLineRunner {
#Autowired
PersonRepository personRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
Thread.sleep(2000);
Person p1 = new Person("1", "prakhar");
personRepository.save(p1);
}
}
Notice that I followed my own advice and did't inherit from AbstractMongoConfiguration
Explanation
The problem lies in the initialization of
#Bean
public MappingMongoConverter mappingMongoConverter() {
return new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
}
You simply call MongoMappingContext constructor, without calling setInitialEntitySet. Compare that with MongoDataConfiguration auto-configuration class.
#Bean
#ConditionalOnMissingBean
public MongoMappingContext mongoMappingContext(MongoCustomConversions conversions)
throws ClassNotFoundException {
MongoMappingContext context = new MongoMappingContext();
context.setInitialEntitySet(new EntityScanner(this.applicationContext)
.scan(Document.class, Persistent.class));
Class<?> strategyClass = this.properties.getFieldNamingStrategy();
if (strategyClass != null) {
context.setFieldNamingStrategy(
(FieldNamingStrategy) BeanUtils.instantiateClass(strategyClass));
}
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
return context;
}
Even worse, you don't register MongoMappingContext as a managed bean.
Due to this fact, auto-configuration class is still created. This leads to a race condition, I tried to run the original code and could easily reproduce the error, but with a breakpoint in AbstractMappingContext.addPersistentEntity the test always passed.
For me I resolved this issue by adding following method in MongoConfig if your class extends from AbstractMongoConfiguration
#Override
protected String getMappingBasePackage() {
return "com.companyName.modulename"
}
If MongoConfig extends from MongoConfigurationSupport then add below method
#Override
protected Collection<String> getMappingBasePackages() {
return Arrays.asList("com.companyName.module1","com.companyName.module2");
}
Note that in later case I can specify multiple package names as base packages.

#unique constraint with database support in hibernate

I have a spring project and want to enforce uniqueness in the database on a field and get the error message back to the UI.
I have read this SO answer and it makes sense so #Column(unique = true) makes the constraint on the table but doesn't enforce it.
So the question becomes how to create a #Unique annotation that checks with the database and returns a error message into BindingResult on POST handler.
An example would be great.
UPDATE
I tried the following way to make a custom validator:
The objects (note I have added #valid to get the validator messages to navigate up to BindingResult)
Person.java
#Entity
public class Person {
public Person() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// other stuff
#UniqueNid
private BigInteger nid;
EpisodePerson.java
#Entity
public class EpisodePerson {
public EpisodePerson(){};
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#Valid
private Person person;
EpisodeViewModel (DTO)
public class EpisodeViewModel {
#Valid
private Episode episode = new Episode();
#Valid
private List<EpisodePerson> persons = new ArrayList<>();
UniqueNid.java
#Documented
#Target({ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = UniqueNiaValidator.class)
public #interface UniqueNid {
String message() default "{Duplicate ID}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
UniqueNidValidator.java
public class UniqueNidValidator implements ConstraintValidator<UniqueNid, BigInteger> {
public UniqueNidValidator(){};
private PersonRepository personRepository;
#Autowired
public void setPersonRepository(PersonRepository personRepository) {this.personRepository = personRepository;}
public UniqueNidValidator(PersonRepository personRepository) {
this.personRepository = personRepository;
}
#Override
public void initialize(UniqueNid constraint) {
}
#Override
public boolean isValid(BigInteger nid, ConstraintValidatorContext context) {
return nid != null && personRepository.existsByNid(nid);
}
}
PersonRepository.java
...
Boolean existsByNid(BigInteger nid);
...
Application.java
#SpringBootApplication
#EnableAutoConfiguration(exclude = { org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class })
public class Demo3Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebApplicationInitializer.class);
}
public static void main(String[] args) {
SpringApplication.run(Demo3Application.class, args);
}
#Bean
public javax.validation.Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
}
When I go to submit a person I get :
Stack Trace (abbreviated)
java.lang.NullPointerException: null
at com.example.validators.UniqueNidValidator.isValid(UniqueNidValidator.java:31) ~[main/:na]
UPDATE 2
I have also tried this configuration
public class UniqueNidValidator implements ConstraintValidator<UniqueNid, BigInteger> {
public UniqueNidValidator(){};
private PersonRepository personRepository;
public UniqueNidValidator(PersonRepository personRepository) {
this.personRepository = personRepository;
}
#Override
public void initialize(UniqueNid constraint) {
}
#Override
public boolean isValid(BigInteger nid, ConstraintValidatorContext context) {
System.out.println("About to check " +nid.toString());
System.out.println("person repo " +personRepository.toString() );
return personRepository.existsByNid(nid);
}
}
which gives:
java.lang.NullPointerException: null
at com.example.validators.UniqueNiaValidator.isValid(UniqueNiaValidator.java:29) ~[main/:na]
When I try to print the repo to console.
You'll need to create a custom validation that checks the database. For the database check you can obviously use the probably already existing Spring Data Repository and it's exists() method.
A custom validation consists of an annotation to mark the fields to be checked and a class implementing the actual check.
On minor challenge is that the class needs a default constructor and doesn't really support injecting dependencies. So anything you need, you have to basically access from some static reference, including e.g. the repository. So you probably have a separate bean which puts the repository into that static reference.
Such a bean that "catches" a repository and makes it available in a static variable might look like this.
#Component
public class RepositoryCatcher{
public static MyRepository;
public RepositoryCatcher(MyRepository r){
repository = r;
}
}
From the exception you mentioned it seems that the only possible NullPointerException is when the personRepository is incorrectly injected to the validator.
Please give a try to the solution below:
Remove the following bean from your Demo3Application and let Spring Boot create the default one instead.
#Bean
public javax.validation.Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
Remove the setter for the repository from the validator but leave the dependency in the constructor as it is right now.
#Autowired
public void setPersonRepository(PersonRepository personRepository {
this.personRepository = personRepository;
}
It's not entirely true that custom validators require a default constructor as mentioned by Jens in his answer. Spring will inject dependencies based on the constructor even though a validator isn't mark as a managed component. The #Autowired annotation is also redundant.
In addition, you probably made a mistake in the condition. You should check if a person doesn't exist (Notice the ! mark in the second part).
return nid != null && !personRepository.existsByNid(nid);
I encourage you to look into a blog post which addresses your issue. Sample code is available in the GitHub repository. You can run, test it, and then compare with your solution.
This is the validator that worked and errors into BindingResult:
UniqueNidValidator.java
public class UniqueNiaValidator implements ConstraintValidator<UniqueNid, BigInteger> {
public UniqueNiaValidator(){};
#Autowired
private PersonRepository personRepository;
public UniqueNiaValidator(PersonRepository personRepository) {
this.personRepository = personRepository;
}
#Override
public void initialize(UniqueNid constraint) {
}
#Override
public boolean isValid(BigInteger nid, ConstraintValidatorContext context) {
return !personRepository.existsByNid(nid);
}
}
Note the !personRepository.existByNid(nid);
Further more the reason that the repo was blank the second time around was because it was getting called twice as outlined here
But checking for RDBMS constraint violations on Beans probably isn't a good idea anyway.

Spring Casheable returned cached objects fail equality check

The issue I am facing is that two objects returned from spring cacheable method with a same key fail assertSame test. Why are these objects not sharing one same storage area?
Details:
I am using redis cache mechanism to implement caching in a spring boot REST api.
The caching works correctly in the way that it first retrieve the data from externally provided source (JPS repository accessing a database) and then subsequent calls for the same cache key returns data from cache. However, I am not able to mimic this behavior completely in the JUnit test cases. My assertEquals or assertSame fail on 2 objects returned from the cache.
my code base looks as below:
mvn dependencies:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.6.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Spring application config:
#SpringBootApplication
#EnableCaching
public class Application {
#Value("${redis.host}")
private String redisHost;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
jedisConFactory.setHostName(redisHost);
jedisConFactory.setPort(6379);
return jedisConFactory;
}
#Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
#Bean
CacheManager cacheManager() {
return new RedisCacheManager(redisTemplate());
}
Service Class:
#Service
public class CIDomainService {
private RedisTemplate<String, Object> redisTemplate;
private CIDomainDAO ciDomainDAO;
#Autowired
public CIDomainService(CIDomainDAO ciDomainDAO, RedisTemplate<String, Object> redisTemplate) {
this.ciDomainDAO = ciDomainDAO;
this.redisTemplate = redisTemplate;
}
#Cacheable(value = "ciDomain", key = "#id")
public CIDomain getCIDomain(int id) {
CIDomain ciDomain = new CIDomain();
ciDomain.setId(id);
ciDomain.setName("SomeName");
return ciDomain;
}
public void clearAllCache() {
redisTemplate.delete("listCIDomains");
redisTemplate.delete("ciDomain");
}
}
ciDomainDAO in the service above is just a JPS repository interface using the findAll() method to retrieve data from external database or in-memory database. My Test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ActiveProfiles("local")
#SpringBootTest
public class CIDomainServiceIntegrationTest {
#Autowired
CIDomainService ciDomainServiceSpy;
#Before
public void setUp(){
ciDomainServiceSpy.clearAllCache();
}
#Test
public void listCIDomains_ShouldRetrieveCIDomainsWithCachingPluggedIn() {
CIDomain domain1 = ciDomainServiceSpy.getCIDomain(1);
CIDomain domain2 = ciDomainServiceSpy.getCIDomain(2);
CIDomain domain3 = ciDomainServiceSpy.getCIDomain(1);
assertSame(domain1, domain3); //fails
}
My Domain Class:
#Entity
#Table(name = "CI_DOMAIN")
public class CIDomain implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
based on this post I understand that object is retrieved from the repository for the very first call and then later call will fetch this object from cache provided same "key" is provided. I am doing the same thing in my test case above but assertSame is failing. Spring cacheable must be caching object in memory which is fetched for a given request. Why would it send different objects everytime for the same requested key.
I have tried to have an alternative solution where I used spy on the service class and verify method calls based on a same key request. However, I encountered different issues in doing that. Creating a spy on the service class does not even use caching mechanism and it does call service getCIDomain method even if same key is provided. I followed this, this, this, this, this and lots of other posts for further analysis but could not get it working either through assertSame of spy.
Any help would really be appreciated.
I had got this issue resolved and was able to design the test case as it should be for verifying spring cacheable mechanism.
Just providing my analysis and resolution below to help someone out there facing this same issue.
I mentioned in my comments and original questions above that assertSame would not work due to how serialization works and assertEquals though was working but it was kind of not satisfying my test requirement.
The conclusion I made (based on comments) that I should actually test number of method calls and not the result. I tried to mock the CIDomainDAO repository dao as in my question but I faced with couple issues. Creating mocked object of CIDomainDAO and passing it in the CIDomainService constructor was not triggering spring cache and my test was failing. If I do not mock CIDomainDAO and tried spying on CIDomainService to check no of method calls and ran my test then I was ending up getting
org.mockito.exceptions.misusing.UnfinishedVerificationException: Missing
method call for verify(mock).
This was obvious as mocking does not seem to work on final methods that CIDomainDAO might have had in its spring generated JPARepository implementation.
This post helped me understand this behavior of mockito.
Concluding that I need to mock CIDomainDAO somehow, I ended up injecting mocked version of CIDomainDAO respository in CIDomainService class. I had to define a CIDomainDAO setter in CIDomainService class specially for this purpose. After that I tried no of method calls and it worked as expected i.e., service called two times but CIDomainDAO called once as the data was returned from the cache in the second call.
Provided below the modified classes from my original question above.
The service class:
#Service
public class CIDomainService {
private RedisTemplate<String, Object> redisTemplate;
private CIDomainDAO ciDomainDAO;
#Autowired
public CIDomainService(CIDomainDAO ciDomainDAO, RedisTemplate<String,
Object> redisTemplate) {
this.ciDomainDAO = ciDomainDAO;
this.redisTemplate = redisTemplate;
}
#Cacheable(value = "ciDomain", key = "#id")
public CIDomain getCIDomain(int id) {
CIDomain ciDomain = new CIDomain();
ciDomain.setId(id);
ciDomain.setName("SomeName");
return ciDomain;
}
public void clearAllCache() {
redisTemplate.delete("listCIDomains");
redisTemplate.delete("ciDomain");
}
public void setCIDomainDAO(CIDomainDAO ciDomainDAO ) {
this.ciDomainDAO = ciDomainDAO;
}
}
And this is the updated test case:
#RunWith(SpringJUnit4ClassRunner.class)
#ActiveProfiles("local")
#SpringBootTest
public class CIDomainServiceIntegrationTest {
#Autowired
#InjectMocks
CIDomainService ciDomainService;
#Mock
CIDomainDAO ciDomainDAO;
#Before
public void setUp() {
Mockito.reset(ciDomainDAO);
ciDomainService.clearAllCache();
}
#Test
public void listCIDomains_ShouldNotAttemptToCallRepositoryWhenCachingEnabledAfterFirstCallOfRetrievingCIDomains() {
List<CIDomain> domains1 = ciDomainService.listCIDomains();
List<CIDomain> domains2 = ciDomainService.listCIDomains();
Mockito.verify(ciDomainDAO, Mockito.times(1)).findAll();
}
#Test
public void listCIDomains_ShouldAttemptToCallRepositoryWhenCachingIsClearedAfterFirstCallOfRetrievingCIDomains() {
List<CIDomain> domains1 = ciDomainService.listCIDomains();
ciDomainService.clearAllCache();
List<CIDomain> domains2 = ciDomainService.listCIDomains();
Mockito.verify(ciDomainDAO, Mockito.times(2)).findAll();
}
#After
public void postSetUp() {
Mockito.validateMockitoUsage();
ciDomainService.clearAllCache();
Mockito.reset(ciDomainDAO);
}
}

#CachePut does not work in #Configuration for pre cache

I was trying to use spring stater-cache in spring boot 1.3.5, everything works fine except pre load cache in #Configuration class.
Failed tests:
CacheTest.testCacheFromConfig: expected:<n[eal]> but was:<n[ot cached]>
Please take a look at the code as below, if you met this before, please share it with me :)
#Component
public class CacheObject{
#CachePut(value = "nameCache", key = "#userId")
public String setName(long userId, String name) {
return name;
}
#Cacheable(value = "nameCache", key = "#userId")
public String getName(long userId) {
return "not cached";
}
}
#Component
public class CacheReference {
#Autowired
private CacheObject cacheObject;
public String getNameOut(long userId){
return cacheObject.getName(userId);
}
}
#Configuration
public class SystemConfig {
#Autowired
private CacheObject cacheObject;
#PostConstruct
public void init(){
System.out.println("------------------");
System.out.println("-- PRE LOAD CACHE BUT DIDN'T GET CACHED");
System.out.println("------------------");
cacheObject.setName(2, "neal");
cacheObject.setName(3, "dora");
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = BootElastic.class)
#WebAppConfiguration
public class CacheTest {
#Autowired
private CacheObject cacheObject;
#Autowired
private CacheReference cacheReference;
#Test
public void testCache(){
String name = "this is neal for cache test";
long userId = 1;
cacheObject.setName(userId, name);
// cacheObject.setName(2, "neal"); // this will make test success
String nameFromCache = cacheReference.getNameOut(userId);
System.out.println("1" + nameFromCache);
Assert.assertEquals(nameFromCache, name);
}
#Test
public void testCacheFromConfig(){
String nameFromCache = cacheReference.getNameOut(2);
System.out.println("4" + nameFromCache);
Assert.assertEquals(nameFromCache, "neal");
}
}
#PostConstruct methods are called right after all postProcessBeforeInitialization() BeanPostProcessor methods invoked, and right before postProcessAfterInitialization() invoked. So it is called before there is any proxy around bean, including one, putting values to cache.
The same reason why you can't use #Transactional or #Async methods in #PostConstruct.
You may call it from some #EventListener on ContextRefreshedEvent to get it working

Why can't i create a neo4j relationship with spring data for neo?

i'm fairly new to spring data for neo (though i have experience with neo4j itself). i tried following the 'official' guide on spring data for neo, specifically the chapter on creating relationships.
But it seems i cannot get it to work. Spring is giving me an
java.lang.IllegalStateException: This index (Index[__rel_types__,Relationship]) has been marked as deleted in this transaction
Let me stress, that i am NOT removing any nodes or relationships. These are the relevant classes of my domain model:
#NodeEntity
public class User {
#GraphId
private Long nodeid;
#Indexed(unique = true)
private String uuid;
....
}
#NodeEntity
public class Website {
#GraphId
private Long nodeid;
#Indexed(unique = true)
private String uuid;
....
}
#RelationshipEntity(type = RelTypes.REL_USER_INTERESTED_IN)
public class UserInterest {
#GraphId
private Long nodeid;
#StartNode
private User user;
#EndNode
private Website site;
...
}
And this is my basic test which i can't get to turn green ..
(note that i omitted large portions of the code, the basic setup of the spring context etc. is working fine)
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
#Transactional
public class BaseTest {
#Autowired
protected Neo4jTemplate template;
#Autowired
protected GraphDatabaseService graphDatabaseService;
protected Transaction tx;
#Configuration
#EnableNeo4jRepositories
static class TestConfig extends Neo4jConfiguration {
TestConfig() throws ClassNotFoundException {
setBasePackage("me.bcfh.model");
}
#Bean
GraphDatabaseService graphDatabaseService() {
return new TestGraphDatabaseFactory().newImpermanentDatabase();
}
}
public void before() {
// provide implementation if necessary
}
public void after() {
// provide implementation if necessary
}
#Before
public void setup() throws Exception {
Neo4jHelper.cleanDb(graphDatabaseService, false);
before();
}
#After
public void tearDown() throws Exception {
after();
if (tx != null) {
tx.success();
tx.close();
tx = null;
}
}
}
public class BasicGraphTest extends BaseTest {
User user;
Website website;
UserInterest interest;
#Override
public void before() {
user = new User();
website = new Website();
website = template.save(website);
user = template.save(user);
}
#Test
#Transactional
public void dbShouldContainData() throws Exception {
UserInterest interest = new UserInterest();
interest.setSite(website);
interest.setUser(user);
template.save(interest);
// some assertions
...
}
}
The IllegalStateException is being thrown when I try persisting the UserInterest instance, which I do not understand because I am not removing anything anywhere.
The ways to create a relationship mentioned in the spring guide did not work for me either, here I got the same exception ..
Can anyone spot what I'm doing wrong here?
I am using Spring Version 4.1.4.RELEASE and Spring Data For Neo Version 3.2.1.RELEASE. Neo4j has version 2.1.6
Note: I also tried copying the domain model classes from the cineasts example into my project and borrowed a few lines of the DomainTest class but this too gives me the IllegalStateException, maybe there is something wrong with my setup?
I think you are getting your IllegalStateException because you are calling cleanDb in your setup method.
You may not need to clean the database. Since your tests are makred #Transactional anything you do in your tests gets rolled back at the end of the test.
Looks like the transaction is trying to rollback and can't find the relationship it expects.

Resources