我陷入了一个明显相当普遍的问题,并想知道我到底做错了什么。Spring Data Neo4j坚持丰富的关系
我有两个类型为“Account”的节点,并且想在它们之间添加一个“FRIEND”关系。但是我不会简单地在对应账户能够接受或拒绝友谊请求(通常流)之前添加关系。所以我创造了一个叫“友谊”的丰富关系。
我的单元测试显示请求将被添加到对应的帐户,但不是在启动器之一。
这里是我的代码的摘录我使用至今:
@Fetch
@RelatedToVia(type = "FRIEND", direction = Direction.BOTH)
private Set<Friendship> friends;
...
...
public void addFriendshipRequest(Friendship friendship) {
this.friends.add(friendship);
}
public Set<Friendship> getConfirmedFriends() {
Set<Friendship> friendships = new HashSet<Friendship>();
for(Friendship f : this.friends) {
if(f.getState() == Friendship.State.CONFIRMED) {
friendships.add(f);
}
}
return friendships;
}
public Set<Friendship> getFriendships() {
return this.friends;
}
public Set<Friendship> getFriendRequests() {
Set<Friendship> requests = new HashSet<Friendship>();
for(Friendship f : this.friends) {
if(f.getState() == Friendship.State.REQUESTED) {
requests.add(f);
}
}
return requests;
}
...
...
}
现在我的 “友谊” 关系的实体
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
import java.io.Serializable;
import java.util.Date;
@RelationshipEntity(type = "FRIEND")
public class Friendship implements Serializable {
public enum State { REQUESTED, CONFIRMED }
@GraphId
private Long id;
@StartNode
private Account requester;
@EndNode
private Account confirmer;
private State state;
private Date dateOfRequest;
private Date dateOfConfirmation;
public Friendship(Account requester, Account target) {
this.state = State.REQUESTED;
this.confirmer = target;
this.requester = requester;
this.dateOfRequest = new Date();
}
public Friendship() { }
... getter/setter and stuff ommitted
}
相应的服务
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import static org.springframework.util.Assert.notNull;
@Service("friendshipService")
@Transactional
@SuppressWarnings("SpringJavaAutowiringInspection")
public class FriendshipServiceImpl implements FriendshipService {
@Autowired
private Neo4jTemplate template;
/**
* request a friendship with another account
*
* @param requester
* @param target
*/
@Override
public void requestFriendship(Account requester, Account target) {
notNull(target);
if(!target.hasFriendshipWith(requester.getId())) {
target.addFriendshipRequest(new Friendship(requester, target));
template.save(target);
}
}
/**
* change pending state of friendship request to CONFIRMED
*
* @param confirmer
* @param requester
*/
@Override
public void acceptFriendshipRequest(Account confirmer, Account requester) {
notNull(confirmer);
for(Friendship f : confirmer.getFriendRequests()) {
if (f.getRequester().equals(requester)) {
f.setState(Friendship.State.CONFIRMED);
f.setDateOfConfirmation(new Date());
}
}
template.save(confirmer);
}
/**
* declines friendship request by removing it
*
* @param confirmer
* @param requester
*/
@Override
public void declineFriendshipRequest(Account confirmer, Account requester) {
notNull(confirmer);
for(Friendship f : confirmer.getFriendRequests()) {
if (f.getRequester().equals(requester)) {
confirmer.getFriendships().remove(f);
}
}
template.save(confirmer);
}
}
和我简单的单元测试检查一切是否顺利...
@ContextConfiguration({"classpath:/test-applicationContext.xml"})
@SuppressWarnings("SpringJavaAutowiringInspection")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestFriendships {
@Autowired
Neo4jTemplate template;
@Autowired
private AccountDetailsService accountDetailsService;
@Autowired
private FriendshipService friendshipService;
private Account myself;
private Account friendlyHans;
private Account unfriendlyPeter;
@Rollback(false)
@BeforeTransaction
public void cleanUpGraph() {
Neo4jHelper.cleanDb(template);
}
@Before
public void prepareTests() {
myself = accountDetailsService.createAccount(new Account("itsme"));
friendlyHans = accountDetailsService.createAccount(new Account("butterflyhans"));
unfriendlyPeter = accountDetailsService.createAccount(new Account("evilmindedpeter"));
}
@Test
@Transactional
public void testSendFriendshipRequest() throws Exception {
friendshipService.requestFriendship(myself, friendlyHans);
assertThat(friendlyHans.getFriendRequests().size(), is(1));
assertThat(myself.getFriendships().size(), is(1));
assertThat(friendlyHans.getFriendRequests().iterator().next().getRequester(), is(myself));
assertThat(friendlyHans.getFriendRequests().iterator().next().getConfirmer(), is(friendlyHans));
assertThat(friendlyHans.getFriendRequests().iterator().next().getState(), is(Friendship.State.REQUESTED));
}
因此,现在当我打电话给friendshipService.requestFriendship(我自己,friendlyHans)时,我认为这两个账户之间的关系将会建立,并且当我指出方向时,我进一步假设,当我检查同行友情列表中,也会有与第一个帐号的关系。不幸的是,这个(assertThat(myself.getFriendships()。size())是(1));)失败,因为该集合是空的。
你能指出我在这里做错了吗?我在过去的几天尝试过 - 不幸的是没有成功。也许这只是一件小事。但我找不到它。
哦,版本号,我使用的是
- 春数据的Neo4j 2.1.0.RELEASE
- 弹簧芯3.2.0.RELEASE
- Neo4j的1.8.1
非常感谢提前。
哦,我的...非常感谢!我认为这很容易......但那很简单?!哈哈......现在像一个迷人的作品。 –