我是Neo4j的新手,我希望将节点(Person)与节点(Asset)连接,但也要存储创建此连接的时间。我发现我必须使用@RelatedtoVia注释。我已经关注了Spring cineasts教程([https://github.com/spring-projects/spring-data-neo4j/tree/master/spring-data-neo4j-examples/cineasts][1])虽然,就测试和数据库群体而言,一切正常但我在REST服务上得到了奇怪的结果。这是我的代码:
节点人
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.*;
@NodeEntity
public class Person {
@GraphId
Long id;
@Indexed
private String displayName;
@Indexed(unique = true, failOnDuplicate = true)
private Long personId;
private String firstName;
private String lastName;
private Date birthday;
private String aboutMe;
private String thumbnailURL;
private String email;
private enum gendertypes {male, female, other};
private gendertypes gender;
private String[] languages;
private boolean active;
public static final String CONSUMED = "CONSUMED";
//empty & full constructor
//getters&setters
@RelatedToVia(type = "CONSUMED", elementClass = ConsumedDate.class)
@Fetch
Iterable<ConsumedDate> consumedDates;
public ConsumedDate consumedDate(Neo4jOperations template, Asset asset, Date timestamp) {
final ConsumedDate consumedDate = template.createRelationshipBetween(this, asset, ConsumedDate.class, CONSUMED, false).consumedDate(timestamp);
return template.save(consumedDate);
}
public Collection<ConsumedDate> getConsumedDates() {
return IteratorUtil.asCollection(consumedDates);
}
}
节点资产
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static org.neo4j.graphdb.Direction.INCOMING;
@NodeEntity
public class Asset {
@GraphId
private Long id;
@Indexed(unique=true, failOnDuplicate = true)
private Long assetId;
private String description;
private String type;
private String[] tags;
public Asset() {}
public Asset(Long assetId, String description, String type, String[] tags) {
this.assetId = assetId;
this.description = description;
this.type = type;
this.tags = tags;
}
public Long getAssetId() {return assetId; }
public void setAssetId(Long assetId) {
this.assetId = assetId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
@RelatedTo(type = "CONSUMED", direction = INCOMING)
Set<Person> persons;
@RelatedToVia(type="CONSUMED", elementClass=ConsumedDate.class, direction=INCOMING)
@Fetch
Iterable<ConsumedDate> consumedDates;
public Collection<Person> getPersons() {
return persons;
}
public Collection<ConsumedDate> getConsumedDates() {
Iterable<ConsumedDate> allConsumedDates = consumedDates;
return allConsumedDates == null ? Collections.<ConsumedDate>emptyList() : IteratorUtil.asCollection(allConsumedDates);
}
@Override
public String toString() {
return "An asset with ID " + assetId + " description " + description + " type " + type;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
if (id == null) return super.equals(o);
return id.equals(asset.id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
关系实体ConsumedDate
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.util.Date;
@RelationshipEntity(type = "CONSUMED")
public class ConsumedDate {
@GraphId
Long id;
@EndNode
Asset asset;
@StartNode
Person person;
Date timestamp;
public ConsumedDate consumedDate(Date timestamp){
this.timestamp=timestamp;
return this;
}
public Asset getAsset() {
return asset;
}
public Person getPerson() {
return person;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConsumedDate consumedDate = (ConsumedDate) o;
if (id == null) return super.equals(o);
return id.equals(consumedDate.id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
控制器
import gr.ntua.sam.context.neo4j.AssetRepository;
import gr.ntua.sam.context.neo4j.LocationRepository;
import gr.ntua.sam.context.neo4j.PersonRepository;
import gr.ntua.sam.context.resources.*;
import com.wordnik.swagger.annotations.ApiOperation;
import org.neo4j.graphdb.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.*;
import java.util.List;
@RestController
@Configuration
@EnableNeo4jRepositories
public class ContextController {
@Autowired
Neo4jTemplate template;
@Autowired
AssetRepository assetRepository;
@Autowired
PersonRepository personRepository;
@ApiOperation(value = "Show the available assets", response = Asset.class)
@RequestMapping(value = "/asset", method = RequestMethod.GET)
public ResponseEntity<List<Asset>> getAssets() throws NotFoundException {
List<Asset> results = assetRepository.all();
return new ResponseEntity<List<Asset>>(results, HttpStatus.OK);
}
@ApiOperation(value = "Create a new asset",response = Asset.class)
@RequestMapping(value = "/asset", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Asset> saveAsset(@RequestBody Asset asset) {
Asset savedAsset = assetRepository.save(asset);
return new ResponseEntity<Asset>(savedAsset, HttpStatus.CREATED);
}
//Persons
@ApiOperation(value = "Get a list of all the available Persons")
@RequestMapping(value = "/person", method = RequestMethod.GET)
public ResponseEntity<List<Person>> getPersons() throws ParseException {
List<Person> results = personRepository.all();
return new ResponseEntity<List<Person>>(results, HttpStatus.OK);
}
@ApiOperation(value = "Creates a new Person node to store information about a user", response = Person.class)
@RequestMapping(value = "/person", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Person> savePerson(@RequestBody Person person) {
Person savedPerson = personRepository.save(person);
return new ResponseEntity<Person>(savedPerson, HttpStatus.CREATED);
}
@ApiOperation(value = "Creates relationship between a Person and an Asset")
@RequestMapping(value = "/person/{personId}/consumes/", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Void> consumes(@PathVariable("personId") Long personId, @RequestBody LinkedAsset linkedAsset) {
Person person = personRepository.findByPersonId(personId);
List<Long> assetIds = linkedAsset.getAssetIDs();
for (Long assetId : assetIds) {
Asset currentAsset = assetRepository.findByAssetId(assetId);
Date date= linkedAsset.getTimestamp();
ConsumedDate consumedDate= person.consumedDate(template,currentAsset,date);
template.save(consumedDate);
}
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
问题在于,当我在Person和Asset之间创建一个关系时,还有一个时间戳(我创建了LinkedAsset类,它充当了JSON输入模型,与Neo4j无关)然后尝试获取通过REST人员或资产,我得到的绝对不是JSON,人或资产出现无限次。有没有办法解决这个问题?
提前谢谢!