我正在尝试将neo4j交叉存储持久性用于稍微设置的数据结构。在jpa和neo4j之间的边界处,它包含一个引用jpa实体的NodeEntity。因此neo4j对象只包含jpa-object的id作为参考。
在mongodb跨存储persitence和neo4j持久性的混合语法中,这可能看起来像这样:
@NodeEntity
public class MyNode {
@GraphId
Long id;
@RelatedTo
MyEntity entity;
... //setters and setters omitted
}
@Entity
public class MyEntity {
@Id @GeneratedValue
Long id;
String name;
... //getters and setters omitted
}
使用spring-data-neo4j似乎无法实现这种跨存储持久性。支持的唯一形式似乎是使用@NodeEntity(“partial = true”),它需要一个jpa表,其id与包含jpa id的neo4j对象相同。
现在,在我看来,实现类似这样的东西的可行方法是截取neo4j的检索和保存,例如:
我对sping-data-neo4j的功能有误吗?
这似乎是一种可行的方法吗?
有没有办法为spring-data-neo4j添加过滤器?我在某种程度上找不到任何东西。或者在弹簧数据甚至弹簧水平上是否有可能有帮助的过滤可能性?
我不是一个春天的专家,所以任何暗示都可能有所帮助。
答案 0 :(得分:3)
我以某种方式解决了这个问题。
我使用Spring的Converter和ConverterFactory可能来隐式地从我的@Entity对象转换为Long,反之亦然。
@NodeEntity如下所示(代码在Scala中 - 但与Java没有相关的区别):
@NodeEntity
class ImplicitUser {
@GraphId
var id: java.lang.Long = _
@Indexed(indexName="username", indexType=IndexType.FULLTEXT)
var username : String = _
@GraphProperty(propertyType = classOf[java.lang.Long])
var person : Person = _
override def toString =
"User %d %s".format(id, username)
}
相关部分是:
@GraphProperty(propertyType = classOf[java.lang.Long])
var person : Person = _
因为这告诉neo4j将该字段保持为Long试图找到一个Spring转换器。因此,需要定义Spring转换。为此,我定义了一个特征,它定义了一个具有Long id的JPA @Entity:
trait JpaLongId {
@Id @GeneratedValue
var id: Long = -1
}
更简单的转换器就是从对象到Id的那个:
class JpaLongIdToLong extends Converter[JpaLongId, java.lang.Long] {
def convert(source : JpaLongId) : java.lang.Long = {
long2Long(source.id)
}
}
换句话说,我必须定义一个工厂以允许实体管理器的DI:
@Component
class LongToJpaLongIdFactory extends ConverterFactory[java.lang.Long, JpaLongId] {
def getConverter[T <: JpaLongId](`type`: Class[T]): Converter[java.lang.Long, T] = {
return new LongToJpaLongId(`type`, em)
}
@PersistenceContext
var em: EntityManager = null
}
class LongToJpaLongId[T <: JpaLongId] extends Converter[java.lang.Long, T] {
private var `type`: Class[T] = null
private var em: EntityManager = null
def this(`type`: Class[T], em: EntityManager) {
this()
this.`type` = `type`
this.em = em
}
def convert(key: java.lang.Long): T = {
return em.find(`type`, key)
}
}
最后,我必须在春季环境中注册这些转换器:
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="at.granul.spring.jpa.LongToJpaLongIdFactory"/>
<bean class="at.granul.spring.jpa.JpaLongIdToLong"/>
</list>
</property>
</bean>
就是这样!现在很容易定义这种“RealtedTo”风格的关系。
欢迎评论和想法。