由于使用@RelatedToVia时的递归关系,无法解析JSON

时间:2015-07-29 15:01:48

标签: json spring rest neo4j

我是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,人或资产出现无限次。有没有办法解决这个问题?

提前谢谢!

0 个答案:

没有答案