How to avoid lazy loading in play framework - jpa

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.

Related

Spring Boot, MongoDB: Fields in Embedded Documents getting Renamed

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.

Merging entity with Play! framework and JPA silently failed

I've been looking around and around without finding any topics related to my situation.
I'm using:
Play! framework v2.5.3 in Java
Hibernate EntityManager v5.1.0.Final
Hibernate JPA 2.1 API v1.0.0.Final
PostgreSQL 9.4
Here the route called with AJAX:
PUT /admin/entity/:id
Which is bound to:
controllers.Entity.update(id: Long)
Here how I handle the update request:
#play.db.jpa.Transactional
public Result update(final long id) {
EntityManager em = _jpa.em("default");
DynamicForm form = _formFactory.form().bindFromRequest();
models.Entity entity;
entity = em.find(models.Entity.class, id);
if (entity == null)
return badRequest();
entity.update(em, form);
em.merge(entity);
return ok();
The method update of Entity change values of the class attributes which are basically String attributes.
My issue: nothing get updated while still executing this piece of code.
I enable SQL log which only display the SELECT query corresponding to em.find() method call. Nothing related to an UPDATE query.
I've been using JPA/EntityManager with Play! for others projects (but with lower version of the framework) without facing this kind of problem.
Any idea why nothing get merged ?
I've been able to fix this issue by writing following piece of code inside
models.Entity.update:
em.getTransaction.begin();
Query query = em.createQuery("UPDATE entity SET value = :v WHERE id = :id");
query.setParameter("value", value);
query.setParameter("id", id);
query.executeUpdate();
em.getTransaction.commit();
But even if this is working, that's not the way how thing should be done... It
doesn't make coffee at all!
Edit: this solution do not work anymore....
I really don't know what I'm doing bad, if any body has an idea about this issue, you're help would be much appreciated.

prolems with DB "save" with #LastModifiedDate and #LastModifiedBy

I've setup Spring Data JPA Auditing as it is described in the docs. I think its configured correctly because on insert, i have all 4 fields (created, createdBy, modified, modifiedBy) filled in correctly.
Now the interesting part. On modification of the entity, everything seems to be running well. I debugged through all the Spring Auditing classes up to the point where in AuditingHandler.java this line:
LOGGER.debug("Touched {} - Last modification at {} by {}", new Object[] { target, defaultedNow, defaultedAuditor });
Looks completely ok. The target has the modified Fields set correctly and i cant see any issues BUT in the database, the two fields wont get updated. (value is still the creation date and user). So somehow it wont get saved. Of course all the other fields get updated including the JPA Version field. So everything but the modified* fields.
I am clueless. Anyone who can help me further how to debug that?
I am using Spring-Data-JPA in 1.9.0 and Spring 4.2.1 together with OpenJPA in the persistence backend.
UPDATE
I think i pinpointed the problem but there is a bug either in OpenJPA oder Spring-Data JPA.
The following class BeanWrapper.java from Spring-Data runs this code:
/*
* (non-Javadoc)
* #see org.springframework.data.mapping.PersistentPropertyAccessor#setProperty(org.springframework.data.mapping.PersistentProperty, java.lang.Object)
*/
public void setProperty(PersistentProperty<?> property, Object value) {
Assert.notNull(property, "PersistentProperty must not be null!");
try {
if (!property.usePropertyAccess()) {
ReflectionUtils.makeAccessible(property.getField());
ReflectionUtils.setField(property.getField(), bean, value);
return;
}
Method setter = property.getSetter();
if (property.usePropertyAccess() && setter != null) {
ReflectionUtils.makeAccessible(setter);
ReflectionUtils.invokeMethod(setter, bean, value);
}
} catch (IllegalStateException e) {
throw new MappingException("Could not set object property!", e);
}
}
JpaPersistentPropertyImpl (property) has usePropertyAccess attribute set to false, thus changing the modified field directly via reflection but this wont get the attribute marked dirty in OpenJPA. When modifying the value to true in the debugger, forcing to use the setter(), everything works fine.
So somewhere is a problem with the way OpenJPA <-> Spring Data interaction. Seems that OpenJPA doesnt like reflection attribute changes and insists on setter().
Is there a way to get this usePropertyAccess property to true?
CONCLUSION
Every journey needs to end. I found out that using #AccessType(AccessType.Type.PROPERTY) on my modified*/created* fields solves the issue. I am not quite sure that the current default -> AccessType.Type.Field is the most sensible one in Spring-Data... at least its not for OpenJPA. IMO this one is pretty hard to to find for non-experienced JPA/Spring developers. Perhaps a note in the documentation would be helpful. I have never used this AccessType property in my life and i am using Spring with OpenJPA for quite some time...

GWT Bean validation does not return all constraint violations in compiled mode

I am experiencing different behavior for client side bean validation when running in gwt development mode than in compiled mode. I have been trying to debug and resolve this issue for hours (days actually) but, although further still did not find the root cause and am currently stuck. Hence my request for help.
In general I have been following the approach advocated here http://www.gwtproject.org/doc/latest/DevGuideValidation.html
and was further more inspired by various articles and questions on StackOverlow. So I have the user enter an object on the client. Than I validate it client side via a call to the validator that has been created by the validator factory.
The problem I am experiencing is that when more than one constraint is validated (i.e. the user enters 2 or more "mistakes") the validator does not (always) return all constraint violations when running in compiled mode, while it does return them all when running in gwt development mode.
The object I try to validate is of the class EnvyMonUser
#Entity
public class EnvyMonUser implements Serializable, Obj<EnvyMonUser> {
private static final long serialVersionUID = 3L;
private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
#Id
private Long id;
#NotNull(message = "company must be selected")
#Index
private Key<Company> companyKey;
#Index
private String googleUserId;
#NotNull(message = "email address must be set")
#Pattern(regexp = EMAIL_PATTERN, message = "invalid email address")
#Index
private String email;
#NotNull(message = "name must be set")
#Size(min = 3, message = "must have a name of minimal 3 characters")
#Index
private String nickName;
#NotNull(message = "location must be selected")
#Index
private Key<SampleLocation> sampleLocationKey;
#NotNull(message = "result must be set")
#Index
private Long value;
...
Where Company and SampleLocation are two other classes. (The annotations #Entity, #Index, #Id and the class Key are of Objectify. I use the same entity class(es) client and server (gae) side. )
Once the user has entered an EnvyMonUser object I validate it via a validator, i.e.
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
...
EnvyMonUser obj = getView().getEditorDriver().flush();
Set<ConstraintViolation<O>> validate = validator.validate(obj);
where my validation factory is
public final class AppValidatorFactory extends AbstractGwtValidatorFactory {
#GwtValidation(value = { MonitorType.class, Measurement.class,
ProgramMeasurement.class, EnvyMonUser.class, Company.class,
SampleLocation.class })
public interface GwtValidator extends Validator {
}
#Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
Am I doing something wrong?
Desperate as I was I tried removing and adding several fields but have not found any logical pattern. Depending on which fields I leave out and also on which of the fields are filled correctly by the user the (missing) constraint(s) in compiled mode change.
I have already tried multiple routes but no success so far. For example at some point I thought this was caused by using objectify. However when I remove sampleLocationKey member it works perfectly fine for companyKey member. I also tried removing the objectify attributes but this also doesn't seem to make a difference.
An interesting thing I did observe (by accident) is that when I remove (comment) some of the members from the hashCode and equals methods the behavior changes. Not sure why this is. Maybe it has something to do with how the validator generator is implemented.
Does anyone have any clue?
Also a pointer in the right direction is appreciated. Does someone for example know where I can find the validator that is generated. Or the sources of the validator generator?
Some versions of libraries I use:
gwt 2.6.0
hibernate-validator-4.1.0.Final.jar
hibernate-validator-4.1.0.Final-sources.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
objectify 4.0.1
Turns out the problem was not in my code but a bug in gwt sources for com.google.gwt.validation.client.impl.ConstraintViolationImpl . See https://groups.google.com/forum/#!topic/Google-Web-Toolkit/xRVGnMWfttc for a full description of the problem and solution.
I had the same issue. The validations were working fine on dev mode and all the error messages were showing up on the UI but in the prod mode we could see only one error message at one time. Late on when debugged and found that my DTO has implemented equals and hashcode method and that what causing this issue. The moment is removed these two implementations from my DTO every things worked fine after that.
I am using GWT 2.6.1.

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; }