ORMLite ID field cannot be compared - java

I have several classes, all of which have an ID field declared as Integer the next way:
#Expose
#DatabaseField(columnName = "_id", id = true)
private Integer idField;
Everything compiles and runs correctly, but when I simply try to check if a record exists:
Integer idField = 1;
result = DBHelper.getHelper().getClassDAO().idExists(idField);
I get the exception:
java.sql.SQLException: Field '_id' is of data type null which can not be compared
The thing is that with one class (let's name it A) the method works properly, but with the others fail and I don't know which is the cause because all the classes have its ID field declared the same way.
I'm getting this exception too if I try to createOrUpdate the object of any class, except the refered class A.
Any helping hand would be appreciated.
NOTE. The project uses an ormlite_config.txt file, which is updated.

After a few hours debugging I came into that the mentioned exception comes only when the class to be saved has one o more collections. As far as I know, the exception is thrown inside the idExists method of the Dao class. Having in mind that the createOrSave method surely must call it, that's why I get the SQLException in both cases.
And now, the workaround to solve this. Rather than invoking the idExists method, I had to create my own like this:
return DBHelper.getHelper().getMyDAO().queryForId(idField) != null;
And instead of calling the createOrUpdate method, first I check if the record exists and then, depending on the result, I call the create or update method of the Dao class I want to persist.

Related

MyBatis update if a field in the source object is not null

Using MyBatis annotation and dynamic SQL, I was trying to update a field of a table only if the corresponding field in the source object is not null. For example, if #{srcField} is not null, set field=#{srcField}. I do not care if the field in DB is null or not.
However, I failed to come up with a correct dynamic SQL.
I tried two dynamic sql approaches. Approach 1 can be taken by my program, but it failed to check if the specific field in the source object is null. Approach 2 causes some run-time error.
My DAO object with setter/getter (source object to update the table):
#Data
public class CityDO {
private Long id;
private String name;
private String description;
}
Mapper using annotation and dynamic sql. I was trying to update the description field, only if record.description is not null.
Approach 1, it failed the test #{description}!=null, even if record.description==null. Each time the produced sql include SET description = ?.
#Update({
"<script>",
"update city",
"<set>",
"<if test='#{description} != null'>description = #{description,jdbcType=VARCHAR},</if>",
"</set>",
"where name = #{name,jdbcType=VARCHAR}",
"</script>"
})
#Override
int update(CityDO record);
Approach 2, the only difference is I added jdbcType in the test condition. The exception is Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'VARCHAR' in 'class com.mycode.CityDO'
"<if test='#{description,jdbcType=VARCHAR} != null'>description = #{description,jdbcType=VARCHAR},</if>",
I appreciate if someone can tell me how to make it working, and if there is a reference solution (even an xml-based one is fine).
The following should work.
<if test='description != null'>
The value of test attribute is evaluated by OGNL while #{} is a MyBatis way of referencing parameter/property.
And, in your case, jdbcTypes may be unnecessary (there is no harm, though).

Generic method to update a field in database

I have a class that implement all my workflow method. At some pointing time, when the request is approved by the workflow, I need to update status in database. For this I need to call the respective service class to save the status. The following method is saving the status in db:
public void changeStatus(String employeeNumber, String carid,String Status) throws Exception {
Car car = carService.findCarByPrimaryKey(carid);
car.setStatus(Status);
carService.saveCarDetails(car);
}
I want to make this method generic since I don't have status for car only. I have to update status for different object depending from the application made. It can be for application for leave/parking...I can keep the field Status with the same name in all table. Please advise me how to proceed.
Thanks
I am not sure , what ORM you are using , like if JPA you are using , you can use find() with class name and primary key as parameters.
May be you can try adding a parameter in changeStatus() as Class class and while calling this changeStatus() method pass the class variable by using getClass() and can perform actions basis of that in changeStatus()

Java Soap Services: Add non-persistent result field based on a persistent one

So I need to add a new field to a SOAP service response. The thing is that the field has to take the value from a persistent field. I cannot add that persistent field directly. The persistent field returns a "Calendar" instance, which is, in fact, a DATETIME from MySQL. The current object uses the XmlAdapter.
I did something like this:
class SomeClassImpl extends SomeClass
{
#Transient
#XmlSchemaType(name="someDate")
private String someDate;
...
public void defSomeDate()
{
this.someDate = this.getPersistentDate().toString();
}
public String retSomeDate()
{
return this.someDate();
}
}
The new field appears in the soap result, but the value is an exception, which I don't remember right now and I am not able to reproduce it now.
How would you do this? Is it possible to annotate a method instead of the member so it appears in the SOAP result? If yes, how would an annootation would look like?
Thank you in advance!
The problem was the following piece of code:
#XmlSchemaType(name="someDate")
There "name" parameter should be one of the standard data types for xml. In this case, because it contains the date and the time, it should be 'dateTime'. It could also be a string, but declaring it as dateTime makes the field more restrictive. Therefore, the correct annotation is:
#XmlSchemaType(name="dateTime")
With the date and time in mind, the second observation is that private String someDate; should be private CalendarsomeDate;, to be consistent and also for the actual code to work.
Annotating the methods is not required. Simply annotating the member/property is enough and as long as the member/property is set somewhere at runtime.
I hope this would be helpful for someone else too. It took me few hours to get this, but now I know how to proceed in the future.

Hibernate same object with different values

I have one class with specific columns, say
Class A
{
private String A;
private String B;
private String C;
// Getter Setter of respectives
}
Now what happened I have same value of column A and column B only column C's value change. So I do something like below
A a = new A();
a.setA(..);
a.setB(..);
for(i=0;i<length;i++){
a.setC(..);
getHibernateTemplate.saveOrUpdate(a);
// or something like this
// A a1 = new A();
// a1 = a;
// a1. setC(..);
// getHibernateTemplate.saveOrUpdate(a1);
}
My issue is it does not store length number of records, it only updates that single record.
I know the reason that hibernate access it as persistent object and even if I change value and again save it will update existing record and it can be resolve by taking new object every time and setting it all values. But I don't want it, is there any way to tell hibernate to save that record instead of updating?
You haven't described actual entity details. If you want to save entity with the same values, set the identifier property as null.
From Documentation -
saveOrUpdate()
if the object is already persistent in this session, do nothing
if another object associated with the session has the same
identifier, throw an exception
if the object has no identifier property, save() it
if the object's identifier has the value assigned to a newly
instantiated object, save() it
if the object is versioned by a or , and the
version property value is the same value assigned to a newly
instantiated object, save() it
otherwise update() the object
saveOrUpdateAll()
Save or update all given persistent instances, according to its id (matching the configured "unsaved-value"?). Associates the instances with the current Hibernate Session.
[If it works, can try this for your other query]
Edit : It's mine oversight, I haven't checked your code carefully.
You have defined object A outside for loop, therefore the same object was being updated in each iteration. Try the below code, might help.
for(i=0;i<length;i++){
A a = new A(); //-- Create new object for each iteration
a.setA(..);
a.setB(..);
a.setC(..);
getHibernateTemplate.saveOrUpdate(a);
}
Yes.Try save(a) instead of saveOrUpdate(a)
getHibernateTemplate.save(a); //each time a new object saves.

SEAM Entity Query on field of sub object

Using seam-gen based code. I have an object "Classroom", which contains an instance of "Location". I want to query for classrooms but specifying a value on the Location object.
Something like 'select from Classroom where Location.State = "NY"'. When I try to bind a selectOneMenu with a list of states to #{ClassroomList.classroom.location.state} I'm getting errors.
Was getting a null pointer exception on Location. I'm assuming I need to instantiate a new "Location" on the Classroom object, but not sure where to do that. On the Classroom entity's constructor? On the ClassroomList backing bean (where the example object is bound to the ClassroomList JSP search fields)?
Yes, you need to instantiate ClassroomList.instance.Location. Because the ClassroomList.instance is not bound to the Database, this is not done automagically
Not sure if this is the best way, but I got it working.
I have a String exposed on my ClassroomList backing bean as "String locationState". My dropdown list of states binds to that
Then that's referenced in my restrictions as:
...
lower(classroom.location.state) like lower(concat(#{classroomList.locationState}, '%'))",
...
--
When I tried to instantiate ClassroomList.instance.Location, I would get:
javax.servlet.ServletException with message: "Id and clazz must not be null"
Not sure what's causing that?

Categories

Resources