I am working on playframework and I have problem with scala forms when i apply the .get() methode to the form to create object i got all the object attributes are null.
here is my code:
import play.data.*;
import static play.data.Form.*;
public static Result save() {
Form<myobj> boundForm = cardForm.bindFromRequest();
if(boundForm.hasErrors()) {
flash("error", "Please correct the form below.");
return badRequest(page1.render(boundForm));
}
myobj temp= boundForm.get();
temp.save();
.
.
.
}
the problem is all the attributes in "temp" are null although when i add breakpoint in the intellij-idea and see the values inside the form i see that it has data
I had the same issue, the data binding stopped working at some point and all attributes was null.
The form.getData() gave back a map where all data was present, but the form's object was empty (all attribute null).
I suspected there is an error with the reflection, so deleted the target directory and compiled the classes again with the play framework. And now it works again.
I think it is a compatibility issue with the idea compiler versus play compiler, but I hadn't investigated the problem further.
Related
I recently upgraded/migrated my Spring Batch Java application from spring-boot-starter-parent-1.5.9.RELEASE to -> spring-boot-starter-parent-2.2.4.RELEASE, which subsequently pulls in the 5.X.X (5.2.3.RELEASE to be exact) springframework dependencies (before I was using 4.X.X). Some of the main ones I'm using are:
spring-boot-starter-parent-2.2.4
spring-boot-starter-batch
spring-boot-starter-jpa
spring-boot-starter-web
hibernate-core
hibernate-envers
hibernate-entitymanager
postgresql
For context, my application reads in .csv files and parses out the data and simply writes it to a postgresql database.
After many hours of debugging today, I know see that my first call to write data to the database, which is done by a JpaRepository method called saveAll(), which basically takes an ArrayList (Iterable) of Entities and batch inserts them to database, is failing somewhere when it enters the JdkDynamicAopProxyClass from the Spring AOP library. Previously, I was using the save() method, but this didn't work anymore once I upgraded my dependencies.
I know its failing here because I debugged meticulously and see that once it hits the saveAll() method in my java class that implements the ItemWriter<S> for Spring Batch, it enters the public Object invoke(Object proxy, Method method, Object[] args) method in the JdkDynamicAopProxyClass, and ends up throwing an exception, after doing a huge weird loop in the library code that's hard to follow.
I also debugged my old Application that WAS WORKING when it was running on spring-boot-starter-1.5.9 as I stated previously, and I see that when it gets to that public Object invoke() method (I mentioned above), it returns an ArrayList of the entities (which is correct) to write to the Database when it hits this line of code inside that method:
public Object invoke(Object proxy, Method method, Object[] args) {
// code here...
// this is where I notice a difference in return type from the "working" code vs. "broken
// code"
retVal = invocation.proceed();
// more code here...
Object var12 = retVal;
return var12;
HOWEVER, when I debugged my new migrated code (that was upgraded to spring 2.X.X/5.X.X, I see it returns a DefaultTransactionStatus#14037 object, which clearly is wrong. It then enters the protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary() method in the TransactionAspectSupport class from the spring-tx library. It will then have the retVal variable in the invoke method I mentioned above equal to null and it will start looping a few times more, over the same parts of code in a circle. It will have the txInfo set as PROPAGATION_REQUIRES_NEW,ISOLATION_SERIALIZABLE. I can click the "Step Into" button in IntelliJ and it will let me step through forever. Its like a infinite loop.
I'm not sure what to post, or if there are any clues here. I googled and found other people have similiar issues, and it seemed to revolve around (possibly) the transaction manager or entity manager and how the Beans were setup in the configuration class.
I tried everything I read, but nothing worked. I'm not an expert with Spring Batch or Spring so maybe I am missing something here.
I also noticed when I was debugging my working code, it had a variable Target = SimpleJpaRepository#11243 and it had some properties like a ArrayList of Providers
Em = Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6f2b608e]
Provider = HIBERNATE
org.hibernate.Session [0]
org.hibernate.jpa.HibernateEntityManager [1]
org.hibernate.ejb.HibernateEntityManager [2]
The odd thing was when I debugged my "broken" code, it seemed to only have the org.hibernate.jpa.HibernateEntityManager in its List in this variable
If anyone can please let me know if there are some clues pointing to something, I would immensely appreciate it. I really think its a Bean config, Entity Manager/Transaction-issue, but I'm not an expert so I'm not sure. I thought it was a dependency issue at first, but after being on google that changed my mind.
I've created a simple Grails app connecting to a table in an Oracle 12 database which is supposed to provide a CRUD for data there. So I have a simple model class like this:
package moduleprototype
class ConfigTest {
int configid
String name
String type
String value
String description
int status
static constraints = {
version false
id column: 'CONFIGID', name:'configid', type: 'integer'
}
}
And the controller:
package moduleprototype
class ConfigTestController {
static scaffold = ConfigTest
}
But when I navigate to the controller in my browser, while all the data from the config_test table is displayed properly, it's all plain text in a table, not clickable links for every value which would allow you to change them (which they should be according to the official guide). Why is that?
The scaffolding is on in the controller so it should theoretically work, and from what I remember from the tutorial app, that was enough for it to automatically allow in-browser modification interface so I'm guessing the reason here is that I'm using an external database instead of the built-in one? How can I fix this so that all the values are again clickable, modifiable and deletable?
EDIT: So to better illustrate my problem, here's an example of scaffolding from the tutorial app where in every row, every value is a link to the /show/ page where a given value can be modified or deleted (which is what I'm trying to achieve):
While in my case, everything (weirdly, apart from the first column, which is my id) is just plain text. The values in the configid column, though, are links, but all just pointing to itself (i.e. /ConfigTest/index).
The scaffolding mechanism needs to find a field named id to work.
Just change your domain class to
package moduleprototype
class ConfigTest {
int id //int configid
String name
String type
String value
String description
int status
static mapping /*constraints*/ = {
version false
id column: 'CONFIGID', name:'id' /*name:'configid'*/, type: 'integer'
}
}
At least that fixed that error for me with a small test with grails 3.3
I am using STS to create a Java webapp.
I have used the following code to set an attribute to an object of the Cat class named myCat.
request.setAttribute("myCat", myCat);
Inside of the Cat class are attributes and the method:
String showAffection(){
return("jumps into your lap and stares at you.");
}
Now, in my .jsp file, I tried to print it with
request.getAttribute("myCat").showAffection();
However, STS is showing me this problem in the .jsp file:
The method showAffection() is undefined for the type Object
What is going wrong? Is this not the correct way to access methods in the object?
I am using Play with Excel module 1.2.3. In a controller, I get a list of Students by calling a method defined in the model - Student:
List<Student> students= Student.findStudents();
findStudents() is defined as:
public static List<Student> findStudents() {
List<Student> list = Student.find("colA != colB").fetch();
return list;
}
then I render the excel file by:
renderExcel("student_report");
Inside the excel template, I have used JXLS. For example:
<jx:forEach items="${students}" var="stu">
${stu.address.name} ${stu.name}
</jx:forEach>
Now, the weird thing happens. stu.name always get displayed fine. However, stu.address.name only get displayed when I have done something like System.out.println(student.address.name) in the code. Otherwise, the cell in the Excel report is blank.
Can anyone explain this?
N.B. Student lazily ref to address
Jxls uses Apache Jexl to process property expressions like stu.address.name. Jexl uses reflection to calculate the object property values.
But reflection and lazy loading do not go along because you work not with a real object but with a proxy object.
When you do System.out.println(student.address.name) the real object is instantiated and the reflection works fine.
Possible solution to the issue is described in this answer Converting Hibernate proxy to real object. Or you just should do eager fetching whenever you need to pass the object to Jxls.
I need to implement a controller that has a command object that is backing a filtering form for a search across multiple entries.
The problem is that the i was asked to do that without using POST request, instead using GET request only, and there before loosing the functionality of the default data binding that springs makes happily for us.
So i tried to implement a method, inside my controller, that looks like this:
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
if (isSearchRequest(request)) {
MyCommandObject myCommandObject = (MyCommandObject) getCommand(request);
System.out.println(managePositionsForm);
}
return super.handleRequestInternal(request, response);
}
But the getCommand returns me a brand new CommandObject with no values, despite that the values are present in the request object (i could retrieve then using the getParameter method of HttpServletRequest). But there isn't any binding.
So the question :
1) Is there any way to archive this?
2) Also is very important, that all the values in the form, are lost and, eventually (if this problem is solved) i will need to "persist" the filters for the users in order to avoid re entering after the first search.
Auto Response : setSessionForm(true); looks like can do the work! (According to javadoc)
Thanks to all!
Greetings
Victor.
Okey, i found a way to archive what a was looking for.
I will explain for the sake of those have the same problem before, and hoping to find a experienced user to validate this method... some quiet common is there a multiple ways to do a same thing and as human beings is very difficult to know without proper acknowledge the right path.. so this i a found looking inside the AbstractFormController (that is excellently documented with javadoc).
So what i did was the following, on my controller constructor i add these lines at the end :
setSessionForm(true);
setBindOnNewForm(true);
That all the magic!
But is not enought with setSessionForm(true). According to javadoc the setBindOnNewForm(boolean) method does the following :
/**
* Set if request parameters should be bound to the form object
* in case of a non-submitting request, i.e. a new form.
*/
So my guess are that these two flags are necessary to be marked as true, because :
The setSessionForm makes posible to store as a session attribute the form object, so "is stored in the session to keep the form object instance between requests, instead of creating a new one on each request" (according to javadoc of the setSessionForm method).
The setBindOnNewForm allows the population of the form object with the initial request (despites what type of request method we have). According the javadoc found the AbstractFormController "Only if bindOnNewForm is set to true, then ServletRequestDataBinder gets applied to populate the new form object with initial request parameters..."
But still i noticed, following the controller flow with a debugger, that the population is happening inside the method "getErrorsForNewForm(HttpServletRequest request)".. that is where a concrete object of type ServletRequestDataBinder is used IF the setBindOnNewForm is true, and later (as the javadoc stated) the onBindOnNewForm method is invoked, allowing the programmer to overwrite it with custom behavior, the default behavior is just empty (again this was double checked against the code of AbstractFormController).
I have an strong felling to validate my thoughts here, so if anyone can help me, that would be alright, besides the problem is solved!
Thanks to all in advance!
Greetings.