Spring Boot Version: 1.5.7.RELEASE
Spring Data
MongoDB
My attempt is to add a simple TODO in TODO Document in MongoDB. I was able to add it if I go by String id.But I want my id to be Long. And my requirement is to generate my own sequence. I am having issues generating sequence with the following code. Appreciate if you point where I am going wrong. I was able to add if I create my own id instead of using a sequence.
package com.srisris.tapasya.springjersey;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import com.srisris.tapasya.springjersey.domain.ToDo;
import com.srisris.tapasya.springjersey.domain.ToDoSequence;
import com.srisris.tapasya.springjersey.repository.ToDoRepository;
import com.srisris.tapasya.springjersey.repository.ToDoSequenceRepository;
#SpringBootApplication(scanBasePackages = { "com.srisris.tapasya.springjersey" })
public class SpringJerseyApplication extends SpringBootServletInitializer implements CommandLineRunner {
#Autowired
private ToDoRepository todoRepository;
/**
* The repository for the sequence {#link ToDoSequence}
*/
#Autowired
private ToDoSequenceRepository sequenceRepo;
// The sequence key name for the books
private static final String ToDo_SEQ_KEY = ToDo.COLLECTION_NAME;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringJerseyApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringJerseyApplication.class, args);
}
#Override
public void run(String... arg0) throws Exception {
todoRepository.deleteAll();
bootStrapToDo();
}
private void bootStrapToDo() throws Exception{
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
Long sequenceId = sequenceRepo.getNextSequenceId(ToDo_SEQ_KEY);
System.out.println(" Sequence ID is " + sequenceId);
ToDo td1 = new ToDo(sequenceId,"Work on Java", "Learn Lambdas, Modules & clojures", dateFormat.format(date));
todoRepository.save(td1);
//ToDo td2 = new ToDo(sequenceRepo.getNextSequenceId(ToDo_SEQ_KEY),"Work on Swift", "Learn Optionals", dateFormat.format(date));
//todoRepository.save(td2);
}
}
ToDo Domain
package com.srisris.tapasya.springjersey.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = ToDo.COLLECTION_NAME)
public class ToDo {
public static final String COLLECTION_NAME = "todos";
#Id
private Long id;
private String summary;
private String description;
private String dateCreated;
public ToDo() {
}
public ToDo(Long todoID, String summary, String description, String dateCreated) {
this.id = todoID;
this.summary = summary;
this.description = description;
this.dateCreated = dateCreated;
}
public Long getId() {
return id;
}
public void setId(Long todoID) {
this.id = todoID;
}
public String getSummary() {
return summary;
}
public String getDescription() {
return description;
}
public String getDateCreated() {
return dateCreated;
}
#Override
public String toString() {
return String.format("ToDo[id=%s, summary='%s', description='%s' , dateCreated='%s']", id, summary, description,
dateCreated);
}
}
Custom Sequence Domain
ToDoSequence
package com.srisris.tapasya.springjersey.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = ToDoSequence.COLLECTION_NAME)
public class ToDoSequence {
public static final String COLLECTION_NAME = "todoSequence";
#Id
private String id;
private Long sequence;
public ToDoSequence() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getSequence() {
return sequence;
}
public void setSequence(Long seq) {
this.sequence = seq;
}
}
ToDoRepository
package com.srisris.tapasya.springjersey.repository;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.srisris.tapasya.springjersey.domain.ToDo;
public interface ToDoRepository extends MongoRepository<ToDo, Long> {
public ToDo findBySummary(String summary);
public List<ToDo> findByDateCreated(String dateCreated);
}
ToDoSequenceRepository
package com.srisris.tapasya.springjersey.repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import com.srisris.tapasya.springjersey.domain.ToDoSequence;
#Repository
public class ToDoSequenceRepository {
#Autowired
private MongoOperations mongoOperation;
public Long getNextSequenceId(String key) throws Exception {
Query query = new Query(Criteria.where("_id").is(key));
// increase sequence id by 1
Update update = new Update();
update.inc("sequence", 1);
// return new increased id
FindAndModifyOptions options = new FindAndModifyOptions();
options.returnNew(true);
// this is the magic happened.
ToDoSequence seqId = mongoOperation.findAndModify(query, update, options, ToDoSequence.class);
// if no id, throws SequenceException
// optional, just a way to tell user when the sequence id is failed to
// generate.
if (seqId == null) {
throw new Exception(seqId + " Unable to get sequence id for key : " + key);
}
return seqId.getSequence();
}
}
Related
I have 1 collection namely profile now since it has lots of properties and since in future I will be needing more properties i decided to add new data in new collection namely profile_details .I will be keeping 1 field in profile_details namely profileId whose value will be same as primary key of collection profile.
I will be saving data of profile in profile collection using profileRepository.save(profile)
In order to save data in profile_details collection I am using aggregation pipeline in order to save data of profile_details collection but $out operator replaces documents instead of inserting new documents.Below is my sample code.Any help will be deeply appreciated
Profile.java
import java.io.Serializable;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.juv.common.bean.model.RecentHealthMetricData;
import com.juv.common.enums.CurrentLanding;
import com.juv.common.enums.MFAPreference;
import com.juv.common.enums.Status;
import com.juv.common.primary.bean.model.Answer;
import com.juv.common.primary.bean.model.DeviceIntegrations;
import com.juv.common.primary.bean.model.DeviceToken;
#Document(collection = "profile")
#JsonIgnoreProperties(ignoreUnknown = true)
#Component
public class Profile extends ProfileDetails implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6608898578832145751L;
#Id
private String profileId;
#Field("kibo_user_id")
#JsonProperty("kibo_user_id")
private String kiboUserId;
#Field("new_recommendations")
#JsonProperty("new_recommendations")
private List<String> newRecommendations;
#Field("kibo_id")
#JsonProperty("kibo_id")
private String kiboId;
#Field("original_kibo_id")
#JsonProperty("original_kibo_id")
private String originalKiboId;
#Field("email")
#JsonProperty("email")
private String email;
#Field("country")
#JsonProperty("country")
private String country;
#Field("first_name")
#JsonProperty("first_name")
private String firstName;
#Field("last_name")
#JsonProperty("last_name")
private String lastName;
#CreatedDate
#Field("created_date")
#JsonProperty("created_date")
private Date createdDate;
#Field("registration_date")
#JsonProperty("registration_date")
private Date registrationDate;
#LastModifiedDate
#Field("last_modified")
#JsonProperty("last_modified")
private Date lastModified;
#Field("phi_mapping_id")
#JsonProperty("phi_mapping_id")
private String phiMappingId;
#Field("phone_number")
#JsonProperty("phone_number")
private String phoneNumber;
#Field("origin")
#JsonProperty("origin")
private String origin;
#Field("gender")
#JsonProperty("gender")
private String gender;
#Field("status")
#JsonProperty("status")
private Status status;
#Field("current_landing")
#JsonProperty("current_landing")
private CurrentLanding currentLanding;
#Field("mfa_preference")
#JsonProperty("mfa_preference")
private MFAPreference mfaPreference;
#Field("profile_recommendation_info_id")
#JsonProperty("profile_recommendation_info_id")
private String profileRecommendationInfoId;
#Field("oldest_profile_recommendation_info_id")
#JsonProperty("oldest_profile_recommendation_info_id")
private String oldestProfileRecommendationInfoId;
#Field("last_question")
#JsonProperty("last_question")
private String lastQuestion;
#Field("answers")
#JsonProperty("answers")
private Answer[] answers;
#Field("is_account_locked")
#JsonProperty("is_account_locked")
private boolean isAccountLocked;
#Field("device_integrations")
#JsonProperty("device_integrations")
private DeviceIntegrations deviceIntegrations ;
#Field("profile_photo")
#JsonProperty("profile_photo")
private String profilePhoto;
#Field("device_token_list")
#JsonProperty("device_token_list")
private List<DeviceToken> deviceTokenList;
#Field("unit_map")
#JsonProperty("unit_map")
private Map<String,String> unitMap;
#Field("recent_health_metric_values")
#JsonProperty("recent_health_metric_values")
private Map<String,RecentHealthMetricData> recentHealthMetricValues;
#Field("last_recommendation_info_date")
#JsonProperty("last_recommendation_info_date")
private Date lastRecommendationInfoDate;
#Field("terms_conditions")
#JsonProperty("terms_conditions")
private boolean termsConditions;
#Field("health_metric_preferences")
#JsonProperty("health_metric_preferences")
private Map<String, String> healthMetricPreferences;
#Field("device_preferences")
#JsonProperty("device_preferences")
private Map<Integer, String> devicePreferences;
#Field("pinpoint_custom_atributes")
#JsonProperty("pinpoint_custom_atributes")
private Map<String,String> pinpointCustomAttributes;
#Field("opt_juvlab_customer")
#JsonProperty("opt_juvlab_customer")
private boolean optJuvLabsCustomer;
#Field("deleted")
#JsonProperty("deleted")
private boolean deleted;
#Field("deleted_timestamp")
#JsonProperty("deleted_timestamp")
private Instant deletedTimestamp;
#Field("daily_action_count_clevertap")
#JsonProperty("daily_action_count_clevertap")
private int dailyActionCountClevertap;
public String getProfileId() {
return profileId;
}
public void setProfileId(String profileId) {
this.profileId = profileId;
}
public String getKiboUserId() {
return kiboUserId;
}
public void setKiboUserId(String kiboUserId) {
this.kiboUserId = kiboUserId;
}
public String getKiboId() {
return kiboId;
}
public void setKiboId(String kiboId) {
this.kiboId = kiboId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
if (email != null) {
email = email.toLowerCase();
}
this.email = email;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public String getPhiMappingId() {
return phiMappingId;
}
public void setPhiMappingId(String phiMappingId) {
this.phiMappingId = phiMappingId;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public CurrentLanding getCurrentLanding() {
return currentLanding;
}
public void setCurrentLanding(CurrentLanding currentLanding) {
this.currentLanding = currentLanding;
}
public MFAPreference getMfaPreference() {
return mfaPreference;
}
public void setMfaPreference(MFAPreference otpPreference) {
this.mfaPreference = otpPreference;
}
public String getProfileRecommendationInfoId() {
return profileRecommendationInfoId;
}
public void setProfileRecommendationInfoId(String profileRecommendationInfoId) {
this.profileRecommendationInfoId = profileRecommendationInfoId;
}
public String getLastQuestion() {
return lastQuestion;
}
public void setLastQuestion(String lastQuestion) {
this.lastQuestion = lastQuestion;
}
public Answer[] getAnswers() {
return answers;
}
public void setAnswers(Answer[] answers) {
this.answers = answers;
}
public boolean isAccountLocked() {
return isAccountLocked;
}
public void setAccountLocked(boolean isAccountLocked) {
this.isAccountLocked = isAccountLocked;
}
public enum ORIGIN {
APP,
KIBO,
SHOPIFY
}
public String getProfilePhoto() {
return profilePhoto;
}
public void setProfilePhoto(String profilePhoto) {
this.profilePhoto = profilePhoto;
}
public DeviceIntegrations getDeviceIntegrations() {
return deviceIntegrations;
}
public void setDeviceIntegrations(DeviceIntegrations deviceIntegrations) {
this.deviceIntegrations = deviceIntegrations;
}
public List<DeviceToken> getDeviceTokenList() {
return deviceTokenList;
}
public void setDeviceTokenList(List<DeviceToken> deviceTokenList) {
this.deviceTokenList = deviceTokenList;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Map<String, String> getUnitMap() {
return unitMap;
}
public void setUnitMap(Map<String, String> unitMap) {
this.unitMap = unitMap;
}
public Date getLastRecommendationInfoDate() {
return lastRecommendationInfoDate;
}
public void setLastRecommendationInfoDate(Date lastRecommendationInfoDate) {
this.lastRecommendationInfoDate = lastRecommendationInfoDate;
}
public boolean isTermsConditions() {
return termsConditions;
}
public void setTermsConditions(boolean termsConditions) {
this.termsConditions = termsConditions;
}
public Map<String, String> getHealthMetricPreferences() {
return healthMetricPreferences;
}
public void setHealthMetricPreferences(Map<String, String> healthMetricPreferences) {
this.healthMetricPreferences = healthMetricPreferences;
}
public Map<String, String> getPinpointCustomAttributes() {
return pinpointCustomAttributes;
}
public void setPinpointCustomAttributes(Map<String, String> pinpointCustomAttributes) {
this.pinpointCustomAttributes = pinpointCustomAttributes;
}
public Map<Integer, String> getDevicePreferences() {
return devicePreferences;
}
public void setDevicePreferences(Map<Integer, String> devicePreferences) {
this.devicePreferences = devicePreferences;
}
public Map<String, RecentHealthMetricData> getRecentHealthMetricValues() {
if(recentHealthMetricValues==null) {
recentHealthMetricValues = new HashMap<>();
}
return recentHealthMetricValues;
}
public void setRecentHealthMetricValues(Map<String, RecentHealthMetricData> recentHealthMetricValues) {
this.recentHealthMetricValues = recentHealthMetricValues;
}
public List<String> getNewRecommendations() {
return newRecommendations;
}
public void setNewRecommendations(List<String> newRecommendations) {
this.newRecommendations = newRecommendations;
}
public boolean isOptJuvLabsCustomer() {
return optJuvLabsCustomer;
}
public void setOptJuvLabsCustomer(boolean optJuvLabsCustomer) {
this.optJuvLabsCustomer = optJuvLabsCustomer;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public Instant getDeletedTimestamp() {
return deletedTimestamp;
}
public void setDeletedTimestamp(Instant deletedTimestamp) {
this.deletedTimestamp = deletedTimestamp;
}
public String getOriginalKiboId() {
return originalKiboId;
}
public void setOriginalKiboId(String originalKiboId) {
this.originalKiboId = originalKiboId;
}
public String getOldestProfileRecommendationInfoId() {
return oldestProfileRecommendationInfoId;
}
public void setOldestProfileRecommendationInfoId(String oldestProfileRecommendationInfoId) {
this.oldestProfileRecommendationInfoId = oldestProfileRecommendationInfoId;
}
public int getDailyActionCountClevertap() {
return dailyActionCountClevertap;
}
public void setDailyActionCountClevertap(int dailyActionCountClevertap) {
this.dailyActionCountClevertap = dailyActionCountClevertap;
}
}
ProfileDetails.java
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import com.fasterxml.jackson.annotation.JsonProperty;
#Document(collection = "profile_details")
public class ProfileDetails {
#Field("profile_id")
private String profileId;
#Field("partner_code")
#JsonProperty("partner_code")
private String partnerCode;
public String getProfileId() {
return profileId;
}
public void setProfileId(String profileId) {
this.profileId = profileId;
}
public String getPartnerCode() {
return partnerCode;
}
public void setPartnerCode(String partnerCode) {
this.partnerCode = partnerCode;
}
}
ProfileFragmentRepositoryImpl.java
package com.juv.common.secondary.repository.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayElemAt;
import org.springframework.data.mongodb.core.aggregation.LimitOperation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.OutOperation;
import org.springframework.data.mongodb.core.aggregation.SetOperation;
import org.springframework.data.mongodb.core.aggregation.SortOperation;
import org.springframework.data.mongodb.core.aggregation.UnsetOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;
import com.juv.common.constants.CommonConstants;
import com.juv.common.secondary.dao.Profile;
import com.juv.common.secondary.dao.ProfileDetails;
import com.juv.common.secondary.repository.ProfileFragmentRepository;
import com.juv.common.secondary.repository.ProfileRepository;
import com.mongodb.internal.operation.InsertOperation;
#Component
public class ProfileFragmentRepositoryImpl implements ProfileFragmentRepository {
#Autowired
private MongoTemplate secondaryMongoTemplate;
#Autowired
private ProfileRepository profileRepository;
#Override
public void saveProfileDetails(Profile profile) {
MatchOperation filterOnProfileId = Aggregation.match(Criteria.where("profileId").is(profile.getProfileId()));
SetOperation setProfileId = SetOperation.set("profileId").toValue(profile.getProfileId());
SetOperation setPartnerCode = SetOperation.set("partnerCode").toValue(profile.getPartnerCode());
OutOperation outOperation = new OutOperation("profile_details").uniqueKey("profileId").insertDocuments();
Aggregation aggregation = Aggregation.newAggregation(filterOnProfileId,setProfileId,setPartnerCode,outOperation);
System.out.println("------------------------"+aggregation);
AggregationResults<ProfileDetails> output = secondaryMongoTemplate.aggregate(aggregation, Profile.class, ProfileDetails.class);
System.out.println("------------------------"+output);
}
}
$out operator replaces documents instead of inserting new documents.How can i make them insert data instead of replacing them
I am using the springio accessing-neo4j-data-rest example which has the relationship as part of the Person class and really doesn't show the advantage of Neo4j. I tried creating a Family relationship entity, but can't create a relationship using a restful service with Springboot and port 8080.
My service works and creates the relationship using http://localhost:7474/db/data/node/67/relationships
Shouldn't I be able to do this (where 66 and 67 are existing Person entities):
POST to http://localhost:8080/people/67/family
{
"to" : "http://localhost:8080/people/66",
"type" : "RELATED_TO"
}
I get the error:
{
"timestamp": 1486948326367,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/people/67/family"
}
Person.java
package hello;
import java.util.HashSet;
import java.util.Set;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
#NodeEntity
public class Person {
#GraphId public Long id;
private String firstName;
private String lastName;
#Relationship(type = Family.TYPE, direction = Relationship.UNDIRECTED)
private Set<Family> family = new HashSet<Family>();
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Set<Family> getFamily() {
return family;
}
public void addFamily(Family f) {
family.add(f);
}
public void addFamily(Person target, String association) {
this.family.add(new Family(this, target, association));
}
public void addFamily(Person target) {
this.family.add(new Family(this, target));
}
}
Family.java
package hello;
import org.neo4j.ogm.annotation.EndNode;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.Property;
import org.neo4j.ogm.annotation.RelationshipEntity;
import org.neo4j.ogm.annotation.StartNode;
#RelationshipEntity(type = Family.TYPE)
public class Family {
public static final String TYPE = "RELATED_TO";
#GraphId
private Long id;
#Property
private String association;
#StartNode
private Person p1;
#EndNode
private Person p2;
public Family() {
}
public Family(Person first, Person second) {
this.p1 = first;
this.p2 = second;
}
public Family(Person first, Person second, String assoc) {
this.p1 = first;
this.p2 = second;
association = assoc;
}
public Long getId() {
return id;
}
public Person getFirst() {
return p1;
}
public Person getSecond() {
return p2;
}
public String getAssociation() {
return association;
}
public void setAssociation(String association) {
this.association = association;
}
}
PersonRepository.java
package hello;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
#RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
List<Person> findByLastName(#Param("name") String name);
List<Person> findByFirstName(#Param("name") String name);
}
FamilyRepository .java
package hello;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
#RepositoryRestResource(collectionResourceRel = "family", path = "family") // what should go here????
public interface FamilyRepository extends GraphRepository<Family> {
// //creates a get - need a post
// #Query("MATCH (a:Traveler),(b:Traveler) WHERE a.lastName = {from} AND b.lastName = {to} CREATE (a)-[r:RELATED_TO]->(b) RETURN r")
// void worksWith(#Param("to") String to);
}
Edited:2-19-2017 - Getting closer. I needed a controller - something like this:
#RestController
public class FamilyController {
...
#RequestMapping(value = "/people/{id}/family", method = RequestMethod.POST, consumes = APPLICATION_JSON, produces = APPLICATION_JSON)
#ResponseStatus(value = HttpStatus.ACCEPTED)
#ResponseBody
Family addFamily(#RequestBody Family f, #PathVariable(value = "id") String id) {
I developed an messaging EJB application with its services that uses WILDFLY 9 server.
Now the application is working and the database is fully functional, I am trying to develop a REST web-service for this app. So I created my RestActivator :
package tn.carmate.webservice;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("rest")
public class RestActivator extends Application {
}
and my messageRessources.java as follows
package tn.carmate.webservice;
import java.util.List;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import tn.esprit.pi.Services.Services;
import tn.esprit.pi.persistance.Message;
#Path("message")
#RequestScoped
public class MessageRessource {
#EJB
Services servicemessage;
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("{idreceiver}")
public Response getMessageList(#QueryParam(value = "idreceiver") int idReceiver) {
List<Message> message = servicemessage.getMessageList(idReceiver);
return Response.status(Status.OK).entity(message).build();
}
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Path("{idSrc/idDest/content}")
public Response sendMessage(#QueryParam(value = "idSrc") int idSrc, #QueryParam(value = "idDest") int idDest,
#QueryParam(value = "content") String content) {
servicemessage.sendMessage(idSrc, idDest, content);
return Response.status(Status.OK).build();
}
#DELETE
#Path("{idm}")
public Response deleteMessage(#QueryParam(value = "idm") int id) {
servicemessage.deleteMessage(id);
return Response.status(Status.OK).build();
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("{idSender/idReceiver}")
public Response getConversation(#QueryParam(value = "idSender") int idSender,
#QueryParam(value = "idReceiver") int idReceiver) {
List<Message> conversion = servicemessage.getConversation(idSender, idReceiver);
return Response.status(Status.OK).entity(conversion).build();
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("{idR}")
public Response returnInbox (#QueryParam(value = "idR")int idR){
List<Message> listmessage = servicemessage.returnInbox(idR);
return Response.status(Status.OK).entity(listmessage).build();
}
#DELETE
#Path("{idc}")
public Response deleteConversation(#QueryParam(value = "idc")int id){
servicemessage.deleteConversation(id);
return Response.status(Status.OK).build();
}
}
but whenever I try to consume a service like this one I get this error:
This is the message Entity
package tn.esprit.pi.persistance;
import java.io.Serializable;
import java.lang.String;
import java.util.Date;
import javax.persistence.*;
/**
* Entity implementation class for Entity: Message
*
*/
#Entity(name="message")
public class Message implements Serializable {
/* #EmbeddedId
private MessageId Id;
*/
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String object;
private String content;
#Temporal(TemporalType.TIMESTAMP)
private Date dateEmission;
#ManyToOne
private User sender;
#ManyToOne
private User receiver;
private static final long serialVersionUID = 1L;
public Message(User src, User dest, String content) {
this.sender = src;
this.receiver = dest;
this.content = content;
this.dateEmission = new Date();
}
public Message() {
super();
}
/* public MessageId getId() {
return Id;
}public void setId(MessageId id) {
Id = id;
}
*/
public int getIdMessage() {
return this.id;
}
public String getObject() {
return this.object;
}
public void setObject(String object) {
this.object = object;
}
public User getReceiver() {
return this.receiver;
}
public void setReceiver(User reciver) {
this.receiver = reciver;
}
public User getSender() {
return this.sender;
}
public void setSender(User sender) {
this.sender = sender;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
public Date getDateEmission() {
return this.dateEmission;
}
public void setDateEmission(Date dateEmission) {
this.dateEmission = dateEmission;
}
}
Double check your URL, I think it should be
http://localhost:8080 not http://localhost:18080. Just a typo mistake.
Secondly, Application base path for restful services set to rest
so url should be
http://localhost:8080/CarMate-web/rest/message?idreceiver=1
Finally, idreceiver is a Query Parameter but #Path("{idreceiver}") treat it as path parameter.
So, In http://localhost:8080/CarMate-web/rest/message?idreceiver=1
Rest Endpoint expect a path variable after /message/{idreceiver}?idreceiver=1 as mentioned by #Leonardo in comments.
I would suggest any of below listed solutions:
Remove #Path from method
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getMessageList(#QueryParam(value = "idreceiver") int idReceiver) {
List<Message> message = servicemessage.getMessageList(idReceiver);
return Response.status(Status.OK).entity(message).build();
}
and use this URL: http://localhost:8080/CarMate-web/rest/message?idreceiver=1
Or Change #Path("{idreceiver}") to #Path("idreceiver")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("idreceiver")
public Response getMessageList(#QueryParam(value = "idreceiver") int idReceiver) {
List<Message> message = servicemessage.getMessageList(idReceiver);
return Response.status(Status.OK).entity(message).build();
}
and use this URL: http://localhost:8080/CarMate-web/rest/message/idreceiver?idreceiver=1
I am doing a project where I want to use saveEmployee() method from EmployeeDAO class in EmployeeManager class using a bean.
Employee.java
package com.tutorialspoint.test;
public class Employee {
EmployeeManager employeeManager;
private String fname;
private String lname;
private int dob;
private String add;
private int id;
public void setfname(String fname){
this.fname=fname;
}
public String getfname(){
return fname;
}
public void setlname(String lname){
this.lname=lname;
}
public String getlname(){
return lname;
}
public void setdob(int dob){
this.dob=dob;
}
public int getdob(){
return dob;
}
public void setadd(String add){
this.add=add;
}
public String getadd(){
return add;
}
public void setid(int id){
this.id=id;
}
public int getid(){
return id;
}
public void setEmployeeManager(EmployeeManager employeeManager) {
this.employeeManager = employeeManager;
}
}
EmployeeDAO.java
package com.tutorialspoint.test;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.io.Serializable;
public class EmployeeDAO implements Serializable{
private static final long serialVersionUID = 1L;
//SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int saveEmployee(Employee e){
String fname = e.getfname();
String lname = e.getlname();
int dob=e.getdob();
String add=e.getadd();
int id = e.getid();
Object p[] = {fname, lname,dob,add,id};
String query="insert into employee values(?,?,?)";
return jdbcTemplate.update(query, p);
}
public int deleteEmployee(int id){
String sql ="delete from employee where id = ?";
return jdbcTemplate.update(sql, new Object[]{new Integer(id)});
}
public List<Employee> getAllEmployee(){
ResultSet rs = null;
PreparedStatement pst = null;
System.out.println("Connection starting.");
Connection con = getConnection();
String stm = "Select * from employee";
List<Employee> records = new ArrayList<Employee>();
try {
pst = con.prepareStatement(stm);
pst.execute();
rs = pst.getResultSet();
while(rs.next()){
Employee employee = new Employee();
employee.setfname(rs.getString(1));
employee.setlname(rs.getString(2));
employee.setdob(rs.getInt(3));
employee.setadd(rs.getString(4));
employee.setid(rs.getInt(5));
records.add(employee);
}
} catch (SQLException e) {
e.printStackTrace();
}
return records;
}
public Connection getConnection(){
Connection con = null;
String url = "jdbc:postgresql://localhost:5432/testdb";
String user = "postgres";
String password = "postgres";
try {
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
con = DriverManager.getConnection(url, user, password);
System.out.println("Connection completed.");
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
finally{
}
return con;
}
}
EmployeeManager.java
package com.tutorialspoint.test;
import org.springframework.stereotype.Service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tutorialspoint.test.EmployeeDAO;
import com.tutorialspoint.test.Employee;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
public class EmployeeManager {
//EmployeeDAO employeeDao=new EmployeeDAO();
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
**EmployeeDAO employeeDao= (EmployeeDAO) ctx.getBean("edao");
public void save(){
employeeDao.saveEmployee();
}**
List<Employee>list=employeeDao.getAllEmployee();
}
My code is above. I want to call saveEmployee() method in EmployeeDAO class from EmployeeManager. How can I do that?
public class EmployeeManager {
public void save(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDAO employeeDao = (EmployeeDAO) ctx.getBean("edao");
List<Employee>list = employeeDao.getAllEmployee();
employeeDao.saveEmployee();
}
}
I'm using Toplink Grid(Eclipselink) as the my JPA implementation framework.
I met a a exception as below while I tried to use Criteria to query a Embeddable object:
Exception [EclipseLink-6119] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.QueryException
Exception Description: The join expression
Query Key conInfo
Base domain.de1003.Employee is not valid, or for a mapping type that does not support joining.
Query: ReportQuery(referenceClass=Employee )
at org.eclipse.persistence.exceptions.QueryException.mappingForExpressionDoesNotSupportJoining(QueryException.java:659)
at org.eclipse.persistence.internal.queries.JoinedAttributeManager.prepareJoinExpression(JoinedAttributeManager.java:851)
at org.eclipse.persistence.internal.queries.JoinedAttributeManager.prepareJoinExpressions(JoinedAttributeManager.java:778)
at org.eclipse.persistence.internal.queries.ReportItem.initialize(ReportItem.java:171)
at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1035)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:509)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:822)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:470)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:710)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1038)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:381)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1124)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2917)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1291)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1273)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1247)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:479)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:714)
And the code I tried are as below:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ContactInfo> cq = cb.createQuery(ContactInfo.class);
Root<Employee> root = cq.from(Employee.class);
cq.select(root.<ContactInfo> get("conInfo"));
cq.where(cb.le(root.<Long> get("employId"), 3));
TypedQuery<ContactInfo> q = em.createQuery(cq);
List<ContactInfo> results = q.getResultList();
In Which ContactInfo is an embeddable class consisting of an address and set of phones. Phone is String filed.
Any help will be very appreciated.
I check the question related to this issue:
JPA - Criteria API and EmbeddedId
But it didn't solve my question.
And I can't find any example code.
TO James:
The entity code as below:
package domain.de1003;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.AttributeOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Version;
import oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer;
import org.eclipse.persistence.annotations.Customizer;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
#Entity(name="Employee")
#Table(name="EMPLOYEE")
#Customizer(oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer.class)
public class Employee implements PortableObject,Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "EM_ID")
private long employId;
#Column(name = "FIRSTNAME")
private String firstName;
#Column(name = "LASTNAME")
private String lastName;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="homePhone", column=#Column(name="HOMEPHONE")),
#AttributeOverride(name="workPhone", column=#Column(name="WORKPHONE"))
})
private ContactInfo conInfo;
#Version
private long version;
public long getEmployId() {
return employId;
}
public void setEmployId(long employId) {
this.employId = employId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public ContactInfo getConInfo() {
return conInfo;
}
public void setConInfo(ContactInfo conInfo) {
this.conInfo = conInfo;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
#Override
public void readExternal(PofReader pofReader) throws IOException {
employId = pofReader.readLong(1);
firstName = pofReader.readString(2);
lastName = pofReader.readString(3);
version = pofReader.readLong(4);
}
#Override
public void writeExternal(PofWriter pofWriter) throws IOException {
pofWriter.writeLong(1, employId);
if(firstName != null) pofWriter.writeString(2, firstName);
if(lastName != null) pofWriter.writeString(3,lastName);
pofWriter.writeLong(4, version);
}
#Override
public String toString() {
return "["
+ "employId = " + employId
+ " firstName = " + firstName
+ " lastName = " + lastName
+ " contact inforamtion: " + conInfo
+ "]";
}
}
and Entity ContactInfo
package domain.de1003;
import java.io.IOException;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer;
import org.eclipse.persistence.annotations.Customizer;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
#Embeddable
#Customizer(oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer.class)
public class ContactInfo implements PortableObject,Serializable{
private static final long serialVersionUID = 1L;
#Column(name = "ADDRESS")
private String address;
#Column(name = "HOMEPHONE")
private String homePhone;
#Column(name = "WORKPHONE")
private String workPhone;
#Column(name = "CELLPHONE")
private String cellPhone;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
public String getWorkPhone() {
return workPhone;
}
public void setWorkPhone(String workPhone) {
this.workPhone = workPhone;
}
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
#Override
public void readExternal(PofReader pofReader) throws IOException {
address = pofReader.readString(1);
homePhone = pofReader.readString(2);
workPhone = pofReader.readString(3);
cellPhone = pofReader.readString(4);
}
#Override
public void writeExternal(PofWriter pofWriter) throws IOException {
if(address != null) pofWriter.writeString(1, address);
if(homePhone != null) pofWriter.writeString(2, homePhone);
if(workPhone != null) pofWriter.writeString(3, workPhone);
if(cellPhone != null) pofWriter.writeString(4, cellPhone);
}
#Override
public String toString() {
return "["
+ "address = " + address
+ " homePhone = " + homePhone
+ " workPhone = " + workPhone
+ " cellPhone = " + cellPhone
+ "]";
}
}
For the equivalent JQPL
Query query = em.createQuery("SELECT e.conInfo FROM Employee e where e.employId < 3");
worked.
I tried reproducing this in the latest EclipseLink (a 2.5 nightly) but couldn't. I suspect it might be fixed with criteria API changes to add On support - can you give it a shot to confirm it? You might have to turn off the cache to use the latest version of EclipseLink to test with though.
Check if conInfo is the correct name of your attribute (include your entity code).
Does the equivalent JPQL work?