Spring Boot, MongoDB: Fields in Embedded Documents getting Renamed - mongodb

I have one main document:
#Document
public class MainDocument {
private String name;
private String desc;
private List<Nested> nestedList;
-- More fields/methods --
}
and a document getting embedded:
#Document
public class Nested {
private String nestedUser;
private String nestedTitle;
-- More fields/methods --
}
When attempting to store a new instance of the Nested class in List<Nested>, the fields of the Nested class are getting renamed. For example, nestedTitle becomes title. This wouldn't be a huge deal except for the fact that it is not allowing me to set the value of some of the renamed fields.
I have tried using the #Field("field_name") annotation but the fields will still get renamed and ignore attempts to set their value.
What would be causing some of the fields to get renamed? Am I missing something? About half of the fields get renamed and the rest stay the correct name...
I am testing by using POSTMAN to send JSON requests to the controller for the main document. Even if I use the new field name in the JSON request the value will still not be set.

Figured it out...
Getter method for nestedTitle was named getTitle() so it was renaming it based on the getter methods name. Changed to getNestedTitle() and it stopped getting renamed. Changed the other getter methods for the fields in question and now everything works as expected.
Not sure why it would rename the field's based on the method name but who am I to judge Spring... Posting this answer to save someone else a couple hours of their time.

Related

How to properly add user data using Bloc && How to properly use Google Places API

I'm having difficulties in two areas:
1) When a user successfully logs into their account using phone auth in Firestore, I take them to an "Edit profile" page so they can add their profile information. I get an error saying that I can't add data to a null user class or add data to a class within a class.
I currently have my user class setup something like the following:
class User {
String points;
Name name;
User({this.points, this.name});
}
class Name {
String firstName;
String lastName;
Name({this.firstName, this.lastName})
}
As you can see, I have a class within a class and when I try to add a value, it says I can't. I've tried doing it like
_bloc.user.name.firstName = value
And I've tried like
Name newName = Name();
newName.first = value.
The second one seems to work but it doesn't seem right. I'm hoping you could help me understand how to properly approach adding data for new users when I have a class within a class.
The second issue is understanding how to properly use the Places API. I'm currently learning from the below repo, but it's outdated and there's a couple lines I can't seem to figure out how to change. I also can't seem to find an updated tutorial since the October app crashing update.
https://github.com/alfianlosari/flutter_placez
Thanks in advance for your help!

Ignore play framework form errors at different views

i'd like to know whether I could ignore play standard validation when I want to. For instance, let's imagine I have a Entity called Car just like
#Entity
public class Car{
#Id
private Long id;
#Required
private String model;
#Required
private String hiddenField; //important but doesn't appear in some cases (some usecases)
}
In order to make it clearer, then
Case 1
#(carForm : Form[Car])
#import helper._
#form(routes.controller.foo.bar) {
#inputText(carForm("model"))
<input type="submit">
}
Case 2
#(carForm : Form[Car])
#import helper._
#form(routes.controller.foo.bar) {
#inputText(carForm("model"))
#inputText(carForm("hiddenField"))
<input type="submit">
}
Then I have a Play.data.Form object, and it has errors cause i haven't filled model or the hiddenField that was given as exmple. But, actually, i have some situations that this hidden doesn't even appear (case 1), i mean, there's no input called that, as the user is not allowed to edit it that time. So, if I have two usecases, where at the first, all inputs are there and they are supposed to be filled, but the other one has no 'hiddenField' input, but, altought, it's still required by my model, and, of course, a form submitted without it has error as well, what should I do?. How was I supposed to deal with it? I have one model, but validation may be different in one case to another, and i wanna it to be server side, not jquery nor pure javascript.
I tried to discardErrors through
(Imagine it was submitted from case 1)
MyForm<Car> myCarForm = Form.form(Car.class).bindFromRequest();
//it has errors, sure it does, hiddenField was required and that field didn't even exist at screen.
myCarForm.discardErrors(); //ok, error hashmap is empty right now
myCarForm.get(); // anyway, no value here.
//myCarForm.data(); //for sure i could retrieve field by field and remount object that way, but that looks hacky and hardworking
Then, any solution? Thank u all
I got it reading Play for Java book.
6.4.2 Partial Validation
A common use case is having multiple validation constraints for the same object
model. Because we’re defining our constraint on the object model, it’s normal to have
multiple forms that refer to the same object model. But these forms might have different
validation constraints. To illustrate this use case, we can imagine a simple wizard in
which the user inputs a new product in two steps:
1 The user enters the product name and submits the form.
2 The user enters the product EAN number and the description.
We could validate the product’s name during step 2, but displaying an error message
for the product name at that point would be weird. Fortunately, Play allows you to perform
partial validation. For each annotated value, we need to indicate at which step it
applies. We can do that with the help of the groups attribute from our annotations.
Let’s change our Product model class to do that:
public Product extends Model {
public interface Step1{}
public interface Step2{}
#Required(groups = Step1.class)
public String name;
#Required(groups = Step2.class)
public String ean;
}
Then, at Controller
// We re//strict the validation to the Step1 "group"
Form<Product> productForm =
form(Product.class, Product.Step1.class).bindFromRequest();
Thanks!
Yes you can achieve the solution to this problem. what's happening in this case is every time you map your request to model car it will always look for JPA validations for every property then it looks for validate() method present inside that model, if that method returns null then it doesn't pass any error and perform the normal execution, but if it returns any thing then it maps it to form errors.
You can return error mapping to specific field or you can just return a string that will be considered as a global error.
In your case solution is :
#Entity
public class Car{
#Id
private Long id;
private String model;
private String hiddenField; //important but doesn't appear in some cases (some usecases)
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<ValidationError>();
.
.
.
#Some logic to validate fields#
#if field invalid#
errors.add(new ValidationError("model", "errorMessage"));
.
.
.
return errors.isEmpty() ? null : errors;
}
Note: Just remove the JPA validation and use your logic in validate function to check according to the situation.
Ignores validations, like this:
myCarForm.discardErrors().get();
and does the validation otherwise, Jquery for example.

How to avoid lazy loading in play framework

In play framework, I use following code to fetch values from a table called "Report" which has other relationship tables like "Project","Build" etc.
List<Report> rpts = Report.find.where()
.eq("publish","1")
.eq("functionality_id", Integer.toString(fun.id))
.eq("project_id", currentProject.id)
.eq("prod_build", prod_build)
.eq("loadType_id", loadType_id)
.in("build_id", buildId)
.orderBy("id desc")
.findList();
I get list of values from "Report" table, but all related table values are not populated. They are populated with null.
#Entity
#Table(name="report")
public class Report {
#Id
public int id;
#Constraints.Required
#ManyToOne
#JoinColumn(name="build_id")
public Build build;
#Constraints.Required
#ManyToOne
#JoinColumn(name="project_id")
public Project project;
.
.
}
It was loaded with those values when I tested couple of days ago, but not working today. When I do rpts.get(i).build.release , it gives nullPointerException because build is null here. This code has not been changed in recent days. Wondering why this is happening. Can someone suggest me whether there is any other setting file (like application.conf) that does this lazy loading. Please help.
I've resolved it.
The problem is that I created an Ebean transaction using following code that caused the trouble.
Ebean.beginTransaction();
try{
group.role = "A";
Ebean.update(group);
Ebean.commitTransaction();
} finally {
Ebean.endTransaction();
}
I never suspected that this could would have caused the problem as I put this code in another class file that is not related to this page. Then I changed to following code and everything worked as expected.
#Transactional
public void saveGroup(Group group){
group.role = "A";
Ebean.save(group);
.
.
}
Following documentation in play framework site helped me to identify the culprit. :)
Enhancement of direct Ebean field access (enabling lazy loading) is
only applied to Java classes, not to Scala. Thus, direct field access
from Scala source files (including standard Play 2 templates) does not
invoke lazy loading, often resulting in empty (unpopulated) entity
fields. To ensure the fields get populated, either (a) manually create
getter/setters and call them instead, or (b) ensure the entity is
fully populated before accessing the fields.

Problem with EF STE and Self-Referencing tables

This is my first post here, so I hope everything is fine.
Here is my problem:
I have a table in my database called UserTypes. It has:
ID;
IsPrivate;
Parent_ID;
The relevant ones are the first and the third one.
I have another table called UserTypes_T which has information for the different types, that is language specific. The fields are:
Language_ID;
UserType_ID;
Name;
What I'm trying to achieve is load the entire hierarchy from the UserTypes table and show it in a TreeView (this is not relevant for now). Then, by selecting some of the user types I can edit them in separate edit box (the name) and a combo box (the parent).
Everything works fine until I try to persist the changes in the database. EF has generated for me two entity classes for those tables:
The class for the user types has:
ID;
IsPrivate;
Parent_ID;
A navigational property for the self-reference (0..1);
A navigational property for the child elements;
Another navigational property for the UserTypes_T table (1..*);
The class for the translated information has:
UserType_ID;
Language_ID;
Name;
A navigational property to the UserTypes table (*..1);
A navigational property to the Languages table (*..1);
I get the data I need using:
return context.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
in my WCF Web service. I can add new user types with no problems, but when I try to update the old ones, some strange things happen.
If I update a root element (Parent_ID==null) everything works!
If I update an element where Parent_ID!=null I get the following error:
AcceptChanges cannot continue because the object’s key values conflict with another object in the ObjectStateManager.
I searched all over the internet and read the blog post from Diego B Vega (and many more) but my problem is different. When I change a parent user type, I actually change the Parent_ID property, not the navigational property. I always try to work with the IDs, not the generated navigational properties in order to avoid problems.
I did a little research, tried to see what is the object graph that I get and saw that there were lots of duplicate entities:
The root element had a list of its child elements. Each child element had a back reference to the root or to its parent and so on. You can imagine. As I wasn't using those navigational properties, because I used the IDs to get/set the data I needed, I deleted them from the model. To be specific I deleted points 4 and 5 from the UserTypes entity class. Then I had an object graph with each element only once. I tried a new update but I had the same problem:
The root element was updated fine, but the elements, that had some parents, threw the same exception.
I saw that I had a navigational property in the UserTypes_T entity class, pointing to a user type, so I deleted it too. Then this error disappeared. All the items in the object graph were unique. But the problem remained - I could update my root element with no problems, but when trying to update the children (with no exclusions) I got a null reference exception in the generated Model.Context.Extensions class:
if (!context.ObjectStateManager.TryGetObjectStateEntry(entityInSet.Item2, out entry))
{
context.AddObject(entityInSet.Item1, entityInSet.Item2);//here!
}
I tried to update only the name (which is in UserTypes_T) but the error is the same.
I'm out of ideas and I've been trying to solve this problem for 8 hours now, so I'll appreciate if someone gives me ideas or share their experience.
PS:
The only way I succeeded updating a child object was using the following code to retrieve the data:
var userTypes = argoContext.UserTypes.Include("UserTypes_T").Where(ut => ut.IsPrivate==false).ToList();
foreach (UserType ut in userTypes)
{
ut.UserType1 = null;
ut.UserTypes1 = null;
}
return userTypes;
where UserType1 is the navigational property, pointing to the parent user type and UserTypes1 is the navigational property, holding a list of the child element. The problem here was that EF "fixups" the objects and changes the Parent_ID to null. If I set it back again, EF sets the UserTypes1, too... Maybe there is a way to stop this behavior?
OK everybody, I just found what the problem was and I'm posting the answer if anybody else encounters the same issue.
The problem was that I was making some validation on the server in order to see if there isn't a circular reference between the user types. So, my method on the server looked something like:
using (MyEntities context = new MyEntities())
{
string errMsg = MyValidator.ValidateSomething(context.UserTypes,...);
if (!string.IsNullOrEmpty(errMsg)) throw new FaultException(errMsg);
//some other code here...
context.UserTypes.ApplyChanges(_userType);//_userType is the one that is updated
context.UserTypes.SaveChanges();
}
The problem is that when making the validation, the context is filled and when trying to save the changes, there are objects with the same key values.
The solution is simple - to use different context for validating things on the server:
using (MyEntities validationContext = new MyEntities())
{
//validation goes here...
}
using (MyEntities context = new MyEntities())
{
//saving changes and other processing...
}
Another one can be:
using (MyEntities context = new MyEntities())
{
using (MyEntities validationContext = new MyEntities())
{
//validation
}
//saving changes and other processing...
}
That's it! I hope it can be useful to somebody!

Preventing Validation in Entity Framework 4

I'm using Entity Framework 4 and a Dynamic Data site to expose a bare-bones admin interface to a few users. Working pretty well in general, but I have run into this one problem on a couple of fields on my model.
Several tables have some audit-related fields - CreatedBy, CreatedDate, ModifiedBy, and ModifiedDate. These fields are required in the database and the associated models are marking the properties as non-nullable (all as it should be). However I am handing setting the values for these fields in code - the field templates for the field types mark these specific fields as disabled on the page, and in the SavingChanges event I set these fields to the appropriate values. All works great when I'm updating an existing item.
The problem comes in when I try to create a new item. I want these fields to remain empty on the page and be auto-populated by my code when submitted, but the Field Templates set up RequiredFieldValidators for these fields and won't let me submit them without a value. Normally this would be great, except that I want to prevent EF from validating these fields at the point of page submission.
I realize that I could mark the fields as nullable in the database and that would resolve the issue - it would probably even be just fine from the data standpoint, but I'm not comfortable with doing so - for one thing it's not unlikely that some of the models these fields appear on will be bulk loaded, possibly by someone else, at a later date. I would rather still have the database enforce the non-nullability of these fields. In the field templates I've tried moving the built-in SetUpValidator() call for the RequiredFieldValidator not to run when these specific fields are being loaded, and I've also tried disabling the RequiredFieldValidators and forcing their IsValid property to true. None of these actions allows me to submit the page.
Is there a way to tell EF/Dynamic Data to skip the validation for some fields?
EDIT
As noted below, I also tried marking them nullable in the model and not in the database, which caused an error: Problem in mapping fragments...Non-nullable column...in table...is mapped to a nullable entity property.
EDIT #2
I have found a solution that works, but requires modifying the auto-generated designer file for the entity set, which is fragile at best. I would love to know a "righter" way to do it, but if nothing becomes apparent in the next couple of days I'll post my own answer.
So here are the edits I found I had to make. When allowing the tool to create the entities in the edmx Designer.cs file I get properties like these:
for a datetime on the server side
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.DateTime CreatedDate
{
get
{
return _CreatedDate;
}
set
{
OnCreatedDateChanging(value);
ReportPropertyChanging("CreatedDate");
_CreatedDate = StructuralObject.SetValidValue(value);
ReportPropertyChanged("CreatedDate");
OnCreatedDateChanged();
}
}
for a varchar
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String CreatedBy
{
get
{
return _CreatedBy;
}
set
{
OnCreatedByChanging(value);
ReportPropertyChanging("CreatedBy");
_CreatedBy = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("CreatedBy");
OnCreatedByChanged();
}
}
To make it work without validation for a DateTime property setting the IsNullable parameter of the EdmScalarPropertyAttribute to true is sufficient to avoid the issue. For the String property you also have to change the 2nd parameter of the SetValidValue method call to "true."
All of this said, the only reason that I'm leaving this as it is is because I don't expect to have to regenerated the entities more than once or twice before we move to a different platform for this site. And in this case, merging the version in I have checked in to git with the version generated by the tool allows me to avoid most of the headaches,
Here is my meta information for a read-only auto generated date field. I don't get validation controls validating these fields. Hope this helps.
[ReadOnly(true)]
[DataType(DataType.Date)]
[Column(IsDbGenerated = true, UpdateCheck = UpdateCheck.Never, AutoSync = AutoSync.Never)]
[UIHint("DateTime")]
[Display(Name = "Modified", Order = 1000)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
public object DateModified { get; private set; }