Children are not fetch with Parent in jdo - google-app-engine

i am using gwt with jdo datanucleus. i have requirement to get child with parent. but i am not getting child when access parent.
my code is as following
my parent class is
#PersistenceCapable(identityType = IdentityType.APPLICATION, table = "user")
public class User implements Serializable {
private static final long serialVersionUID = 2660867968471555842L;
#PrimaryKey
#Persistent
private String email;
#Persistent(defaultFetchGroup = "true",mappedBy="user")
private UserProfile profile;
public User() {}
public User(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public UserProfile getProfile() {
return profile;
}
public void setProfile(UserProfile profile) {
this.profile = profile;
}
}
and my child class is
#PersistenceCapable(identityType = IdentityType.APPLICATION,table = "user_profile")
public class UserProfile implements Serializable {
private static final long serialVersionUID = -6818036410894395030L;
#PrimaryKey
#Persistent(defaultFetchGroup="true")
private User user;
#Persistent
private String name;
public UserProfile() {}
public UserProfile(User user) {
this.user = user;
user.setProfile(this);
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
i am fetching data by following query
PersistenceManager pm = PMF.get().getPersistenceManager();
User user=null;
try{
String userId ="abc#abc.com";
Query userQuery = pm.newQuery(User.class);
userQuery.setFilter("email == '" + userId + "'");
userQuery.setUnique(true);
user = (User) userQuery.execute();
} catch (Exception e) {
throw new IllegalAccessError("Failed to get the User..");
}finally{
pm.close();
}
but i am getting userprofile null in object user.
where is the problem ?
how to load children with parent ?

I'm not sure if you found your answer, but for those that stumble across this I just wanted to share how I got it working.
#PersistenceCapable(detachable = "true")
#FetchGroup(name = "fooGroup", members = { #Persistent(name = "list") })
public class ParentClass {
#Persistent(mappedBy = "parent")
#Element(dependent = "true") //can not exist without parent
private List<ChildClass> list;
}
#PersistenceCapable(detachable = "true")
public class ChildClass {
#Persistent
private ParentClass parent;
}
and then to do the fetching:
PersistenceManager pm = PMF.get("eventual-reads-shortdeadlines").getPersistenceManager();
pm.setDetachAllOnCommit(true);
pm.getFetchPlan().addGroup("fooGroup");
Transaction tx = pm.currentTransaction();
try {
tx.begin();
Query query = pm.newQuery(ParentClass.class);
list = (List<ParentClass>) query.execute();
tx.commit();
} catch (Exception ex) {
...
} finally {
if (pm != null) {
if(pm.currentTransaction().isActive()){
pm.currentTransaction().rollback();
}
pm.close();
}
}
Your ParentClass's should now have all the ChildClass's for each. Hope that helps!

Related

Is there a way to create an object with foreign key being null at first and then to set it later in spring boot JPA?

I have a one to one relation between two classes. I want to create phase items without having to insert candidate Id with it, because I get candidates afterwards so they basically don't exist.
Right now I'm getting the error:
could not execute statement; SQL [n/a]; constraint [null];
because i'm not sending candidateId with it.
This is the first class :
public class PhaseItems {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "phaseI_id")
private long id;
private String PhaseItem;
#ManyToMany(fetch = FetchType.LAZY,
mappedBy = "items")
#JsonIgnore
private List<PhaseTemplate> template = new ArrayList<>();
#OneToOne(fetch = FetchType.LAZY, optional = true)
#JoinColumn(name = "candidate_id", nullable = true)
private Candidate candidate;
public PhaseItems() {
super();
}
public PhaseItems(long id, String phaseItem) {
super();
this.id = id;
PhaseItem = phaseItem;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getPhaseItem() {
return PhaseItem;
}
public void setPhaseItem(String phaseItem) {
PhaseItem = phaseItem;
}
public List<PhaseTemplate> getTemplate() {
return template;
}
public void setTemplate(List<PhaseTemplate> template) {
this.template = template;
}
public Candidate getCandidate() {
return candidate;
}
public void setCandidate(Candidate candidate) {
this.candidate = candidate;
}
#Override
public String toString() {
return "PhaseItems [id=" + id + ", PhaseItem=" + PhaseItem + ", template=" + template + "]";
}
This is the second class:
#Entity
#Table(name= "candidats")
public class Candidate {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "candidate_id")
private long id;
private String fullname;
private String username;
#Column(nullable = false, unique = true, length = 45)
private String email;
private String adress;
private String phoneNumber;
private String password;
#Column(name = "status")
private String status;
#OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "candidate")
private PhaseItems phases;
public Candidate(){
}
public Candidate(String fullname,String username,String email, String adress, String phoneNumber, String password,
List<JobApplication> appliedJobs) {
super();
this.fullname = fullname;
this.username = username;
this.email = email;
this.adress = adress;
this.phoneNumber = phoneNumber;
this.password = password;
this.appliedJobs = appliedJobs;
}
public Candidate(String fullname,String username, String email, String adress, String phoneNumber, String password) {
super();
this.fullname = fullname;
this.username = username;
this.email = email;
this.adress = adress;
this.phoneNumber = phoneNumber;
this.password = password;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<JobApplication> getAppliedJobs() {
return appliedJobs;
}
public void setAppliedJobs(List<JobApplication> appliedJobs) {
this.appliedJobs = appliedJobs;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
Set column candidate_id as nullable in your database. Java attribute nullable = true of #JoinColumn annotation is ignored.
Is your column « candidate_id » from table phase_items nullable in your schema ?

Azure AD B2C with Graph API - how to get/set user's email?

I add users to Azure AD B2C with Graph API but I don't get it how to store users' email (the primary one). Which field here is the user's primary email address?
As I read here on SO there's no way to populate values in Authentication contact info. It this correct?
Here's how I do it:
public async Task<AdUser> GetUserByObjectId(Guid objectId)
{
string userJson = await SendGraphGetRequest("/users/" + objectId, null);
JObject jUser = JObject.Parse(userJson);
return new AdUser(jUser);
}
internal AdUser(JObject jUser)
{
AccountEnabled = jUser["accountEnabled"].Value<bool>();
CompanyName = jUser["companyName"].Value<string>();
Department = jUser["department"].Value<string>();
DisplayName = jUser["displayName"].Value<string>();
FirstName = jUser["givenName"].Value<string>();
JobTitle = jUser["jobTitle"].Value<string>();
LastName = jUser["surname"].Value<string>();
MailNickname = jUser["mailNickname"].Value<string>();
Mobile = jUser["mobile"].Value<string>();
ObjectId = new Guid(jUser["objectId"].Value<string>());
List<string> mailList = new List<string>(jUser["otherMails"].Count());
mailList.AddRange(jUser["otherMails"].Select(mail => mail.Value<string>()));
OtherMails = mailList.AsReadOnly();
Phone = jUser["telephoneNumber"].Value<string>();
List<(string type, string value)> signInNames = jUser["signInNames"].Select(jToken => (jToken["type"].Value<string>(), jToken["value"].Value<string>())).ToList();
SignInNames = signInNames.AsReadOnly();
UserPrincipalName = jUser["userPrincipalName"].Value<string>();
UserType = jUser["userType"].Value<string>();
}
and here's the Email property of the AdUser:
public string Email
{
get
{
if (SignInNames.Count > 0 && SignInNames[0].type == "emailAddress")
return SignInNames[0].value;
if (OtherMails.Count > 0)
return OtherMails[0];
throw new InvalidOperationException("Don't know where to get user Email");
}
}
You need to make a PATCH request to the users endpoint
{baseurl}/{tenantId}/users?api-version={apiVersion}
Don't forget you access token in the auth header:
Authorization: Bearer {accessToken}
Here's an example model (Java) with methods for calculating and setting the sign-in email on a user object:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
#JsonIgnoreProperties(ignoreUnknown = true)
public class GraphApiUserExample{
#JsonProperty("objectId")
private String id;
private Boolean accountEnabled;
private PasswordProfile PasswordProfile;
private List<SignInName> signInNames;
private String surname;
private String displayName;
private String givenName;
#JsonProperty("userPrincipalName")
private String userPrincipalName;
public String getId(){
return id;
}
public void setId(final String id){
this.id = id;
}
public Boolean getAccountEnabled(){
return accountEnabled;
}
public void setAccountEnabled(final Boolean accountEnabled){
this.accountEnabled = accountEnabled;
}
public PasswordProfile getPasswordProfile(){
return passwordProfile;
}
public void setPasswordProfile(final PasswordProfile passwordProfile){
this.passwordProfile = passwordProfile;
}
public List<SignInName> getSignInNames(){
return signInNames;
}
public void setSignInNames(final List<SignInName> signInNames){
this.signInNames = signInNames;
}
public String getSurname(){
return surname;
}
public void setSurname(final String surname){
this.surname = surname;
}
public String getDisplayName(){
return displayName;
}
public void setDisplayName(final String displayName){
this.displayName = displayName;
}
public String getGivenName(){
return givenName;
}
public void setGivenName(final String givenName){
this.givenName = givenName;
}
public String getUserPrincipalName(){
return userPrincipalName;
}
public void setUserPrincipalName(final String userPrincipalName){
this.userPrincipalName = userPrincipalName;
}
#JsonIgnore
public String getSignInEmail(){
String email = "";
if(signInNames != null){
for(SignInName signInName : signInNames){
if(signInName.getType().equals("emailAddress")){
email = signInName.getValue();
break;
}
}
}
return email;
}
#JsonIgnore
public void setSignInEmail(String signInEmail){
if(signInNames == null){
signInNames = new ArrayList<>();
signInNames.add(new SignInName("emailAddress", signInEmail));
return;
}
for(SignInName signInName : signInNames){
if(signInName.getType().equals("emailAddress")){
signInName.setValue(signInEmail);
break;
}
}
}
}
SignInName:
public class SignInName {//userName or emailAddress
private String
type,
value;
public String getType(){
return type;
}
public void setType(final String type){
this.type = type;
}
public String getValue(){
return value;
}
public void setValue(final String value){
this.value = value;
}
}
PasswordProfile:
#JsonIgnoreProperties(ignoreUnknown = true)
public class PasswordProfile {
private String password;
private Boolean forceChangePasswordNextLogin;
public String getPassword(){
return password;
}
public void setPassword(final String password){
this.password = password;
}
public Boolean getForceChangePasswordNextLogin(){
return forceChangePasswordNextLogin;
}
public void setForceChangePasswordNextLogin(final Boolean forceChangePasswordNextLogin){
this.forceChangePasswordNextLogin = forceChangePasswordNextLogin;
}
}

Spring MVC + AngularJs: JSON/Model values set to null

I am trying submit json data to a Spring MVC controller mapped with a model. Instead of getting the json values, the values of the fields of the model are all NULL.
IDE debugger:
Chrome:
Exception:
org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!
Controller:
#RequestMapping(value = "/update", method = RequestMethod.POST)
#ResponseBody
public PostResponse update(Setting setting, BindingResult bindingResult) {
return settingService.processUpdate(setting, bindingResult, messageSource);
}
JSON data:
{
"updatedAt":1460600207000,
"id":1,
"createdBy":null,
"description":"This is a setting",
"code":"MY_SETTING",
"value":"{\"id\":\"1018\",\"title\":\"Another setting\",\"code\":\"220-203-10-101\"}"
}
Model:
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Setting {
#Id
#GeneratedValue
#Column
private Integer id;
#Column(unique = true)
private String code;
#Column
private String description;
#Column
private String value;
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date createdAt;
#Temporal(TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date updatedAt;
#NotFound(action = NotFoundAction.IGNORE)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="FK_createdByUserId")
private User createdBy;
public Setting() {}
public Setting(String code, String description, String value, Date createdAt, Date updatedAt, User createdBy) {
this.code = code;
this.description = description;
this.value = value;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.createdBy = createdBy;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public User getCreatedBy() {
return createdBy;
}
public void setCreatedBy(User createdBy) {
this.createdBy = createdBy;
}
I guess that the setting bean is not mapped at all.
You need to tell spring how to map the http request to the method arguments. If you're posting data, the best way is to add #RequestBody annotation to the relevant method argument (setting in your case)
Modify your controller method like this:
#RequestMapping(value = "/update", method = RequestMethod.POST)
#ResponseBody
public PostResponse update(#RequestBody Setting setting, BindingResult bindingResult) {
return settingService.processUpdate(setting, bindingResult, messageSource);
}

Trouble persisting one-to-many relationship using jpa in Google app engine

I have two entities as below and when i try to persist "Category" the "Tip" object list does not get persisted .I noticed that in my DAO class that I was able to see the category object with tipsForCategory list of size 1 but when i try to retrieve after persisting I am able to see only Category details and tipsForCategory comes as empty list.
#Entity
public class Category {
#GeneratedValue
#Id
public Long id;
#Column
public String categoryName;
#OneToMany(mappedBy = "category",cascade = {CascadeType.ALL})
public List<Tip> tipsForCategory;
public Long getId() { return id; }
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName.toLowerCase();
}
public void addTip(Tip tip) {
if(!tipsForCategory.contains(tip)) {
tipsForCategory.add(tip);
}
}
public List<Tip> getTipsForCategory() {
return tipsForCategory;
}
}
Code for Tip Entity
#Entity
public class Tip {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Key key;
#Column
public String tipDescription;
#ManyToOne(cascade = {CascadeType.ALL})
public Category category;
public String getTipDescription() {
return tipDescription;
}
public void setTipDescription(String tipInformation) {
this.tipDescription = tipInformation;
}
}
Code for persisting in my DAO
#Override
#Transactional
public void save(Category category) {
EntityManager localEntityManager=entityManager.getEntityManagerFactory().createEntityManager();
EntityTransaction transaction=localEntityManager.getTransaction();
try {
transaction.begin();
localEntityManager.persist(category);
localEntityManager.flush();
transaction.commit();
}catch (Exception e) {
e.printStackTrace();
localEntityManager.close();
}
}
My retrieval method is
#Override
public CategoryDTO findCategory(Long categoryId) throws FixitException{
CategoryDTO categoryDTO=null;
Category category=categoryDAO.findById(categoryId);
if(category!=null) {
categoryDTO=new CategoryDTO(category);
}
return categoryDTO;
}
#Override
public List<TipDTO> retrieveTips(Long categoryId) throws FixitException{
List<TipDTO> tips=null;
try {
CategoryDTO category = findCategory(categoryId);
if (category != null) {
tips = category.getTipsForCategory();
}
}
catch(Exception e)
{
throw new FixitException(FixitConstants.TIP_RETRIEVAL_ERROR+categoryId,e.getCause());
}
return tips;
}
Looks like the problem was with lazy fetch I just resolved the same.In my categoryDAO.findById(..) code I had to add an additional line to retrieve the tips as below
#Override
public Category findById(Long categoryId) {
Category category=null;
try {
TypedQuery<Category> findByCategoryId = entityManager.createQuery("Select cat from Category cat where cat.id=:categoryId",Category.class);
category=findByCategoryId.setParameter("categoryId", categoryId).getSingleResult();
}
catch (Exception e)
{
e.printStackTrace();
}
*** int tipsSize=category.getTipsForCategory().size();***
return category;
}

JAVA Google App Engine + Facebook API + GSON = Trouble with Javabean

I am trying to get the user's friends list from Facebook.
The problem seems to be the Javabean...
FBUser fbuser = new Gson().fromJson(jsonStr, FBUser.class);
public class FBUser implements Serializable {
private static final long serialVersionUID = -3154429420153433117L;
private String id;
private String name;
private String email;
private Friends friendsList = new Friends();
private FBUser() { }
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Data> getFriendsList() {
return friendsList.getData();
}
public static class Friends implements Serializable {
private static final long serialVersionUID = 6991758772193514527L;
private List<Data> data;
private Friends() { }
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
public class Paging implements Serializable {
private static final long serialVersionUID = 1689816298710621080L;
private String next;
private Paging() { }
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
}
}
public class Data implements Serializable {
private static final long serialVersionUID = -5008541658519841090L;
private String id;
private String name;
private Data() { }
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Json:
json: {"id":"10861234","name":"Whatever","email":"whatever\u0040gmail.com","friends":{"data":[{"name":"Someone","id":"10861234"},{"name" ...43"}],"paging":{"next":"https:\/\/graph.facebook.com\/10861234\/friends..."}}}
The fields ID, Name and Email I can retrieve succesfully... but the friendsList is null... =(
Maybe it is the way I am trying to get it from the nested class, any suggestions on that?
There is no friendsList in your JSON (or, there's no friends in your Java class - whichever way you'd like to look at it). Gson silently ignores anything in the JSON that is not present in your classes.
You have a field friends whose value is an object. That object has a field data which is an array of objects and a field paging which is another object.
You need to write Java classes that match that structure. You're ... close.
In your FBUser class change:
private Friends friendsList = new Friends();
to:
private Friends friends = new Friends();
or:
#SerializedName("friends")
private Friends friendsList = new Friends();
Then in your Friends class you need to add:
private Paging paging = new Paging();
Also note that you don't have to initialize these values unless you specifically don't want them to be non-null when using these classes elsewhere.

Resources