Reputation: 80176
Why is spring-data looking at isCaptain
even when I specified it as transient
? From the documentation, the transient
properties should be ignored. No error if I use a Boolean
wrapper class
Exception
org.springframework.data.mapping.model.MappingException: Setting property isCaptain to null on Player [nodeId=1, name=null, firstName=null, lastName=null]
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:85)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:91)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access$000(SourceStateTransmitter.java:40)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$1.doWithPersistentProperty(SourceStateTransmitter.java:54)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter$1.doWithPersistentProperty(SourceStateTransmitter.java:51)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:240)
at org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:51)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:100)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:92)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.read(Neo4jEntityPersister.java:170)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:244)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:293)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:287)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy38.save(Unknown Source)
at com.aravind.avl.domain.PlayerRepositoryTest.firstNameExactMatchOnly(PlayerRepositoryTest.java:53)
ENTITY
@NodeEntity
public class Player
{
@GraphId
private Long nodeId;
@GraphProperty
@Indexed
private String firstName;
@GraphProperty
@Indexed
private String lastName;
private transient boolean isCaptain;
}
JUNIT
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/testContext.xml" })
@Transactional
public class PlayerRepositoryTest
{
@Autowired
PlayerRepository repo;
Player p;
@Before
public void setUp()
{
p = new Player();
p.setName("Aravind Yarram");
}
@Test
public void firstNameFullTextSearch()
{
Player save = repo.save(p);
assertNotNull(save);
assertNotNull(p.getNodeId());
EndResult<Player> players = repo.findAllByQuery("firstName", "A*");
assertNotNull("Starts with first letter match", players.single());
// TODO not supported
// players = repo.findAllByQuery("firstName", "aravind");
// assertNotNull("Lower-case mathch", players.single());
}
@Test
public void firstNameExactMatchOnly()
{
Player save = repo.save(p);
assertNotNull(save);
assertNotNull(p.getNodeId());
// either use domain specific method
Player result = repo.findByPropertyValue("firstName", p.getFirstName());
assertNotNull("findByPropertyValue should be used for EXACT matches", result);
// or generic method
result = repo.findPlayerByFirstName(p.getFirstName());
assertNotNull("Exact mathch", result);
}
}
Upvotes: 2
Views: 1076
Reputation: 80176
@Transient
as suggested by Sotirios Delimanolis works. I believe the transient
keyword isn't honored because it can conflict with use-cases where Serialization is required. For e.g. you might want the isCaptain
property to be available in web session but not required to be saved to the neo4j, my exact situation.
Upvotes: 1