Eclipselink ScrollableCursor fails on second next() call - jpa

I am trying to use ScrollableCursor for loading all users of the system to memory.
I have a code like this:
Query findUsersQuery
= entityManager.createNamedQuery(UserEntity.QUERY_ALL_USERS, UserEntity.class);
findUsersQuery.setHint(QueryHints.SCROLLABLE_CURSOR, Boolean.TRUE);
findUsersQuery.setHint(QueryHints.CURSOR_PAGE_SIZE, bulkSize);
findUsersQuery.setMaxResults(maxInitialCacheSize);
ScrollableCursor scrollableCursor = (ScrollableCursor) findUsersQuery.getSingleResult();
int leftSize = scrollableCursor.size();
while (scrollableCursor.hasNext()) {
int nextSize = leftSize > bulkSize ? bulkSize : leftSize;
List subscriberPrefs = scrollableCursor.next(nextSize);
leftSize -= nextSize;
//... Result list processing
}
The query is: SELECT s FROM UserEntity u order by u.userId
Size of result table is 100, when scrollableCursor.next(nextSize); called, i get following exception:
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLRecoverableException: Closed Resultset
Error Code: 17010
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.cursorRetrieveNextRow(DatabaseAccessor.java:447)[215:org.eclipse.persistence.core:2.4.1.v20121003-ad44345]
at org.eclipse.persistence.queries.ScrollableCursor.retrieveNextObject(ScrollableCursor.java:563)[215:org.eclipse.persistence.core:2.4.1.v20121003-ad44345]
at org.eclipse.persistence.queries.ScrollableCursor.loadNext(ScrollableCursor.java:411)[215:org.eclipse.persistence.core:2.4.1.v20121003-ad44345]
at org.eclipse.persistence.queries.ScrollableCursor.next(ScrollableCursor.java:437)[215:org.eclipse.persistence.core:2.4.1.v20121003-ad44345]
at org.eclipse.persistence.queries.ScrollableCursor.next(ScrollableCursor.java:459)[215:org.eclipse.persistence.core:2.4.1.v20121003-ad44345]
While calling next(10) the first row loaded normally and the exceptions occurs on second row. I don't have an idea why. Can anybody say how i can avoid this error?

Related

Enity Framework Issue-

i have table name M_Lovs with columns TITLE,TYPE_ID,IS_ACTIVE,AMD_BY,AMD_ON and ID. ID is primary key and its autoincremented. When i try to save my table using entity framework it throws 'System.Data.Entity.Infrastructure.DbUpdateException'.. when i checked the inner exception i found '{"An error occurred while updating the entries. See the inner exception for details."}' exception.
My code is as follows
M_LOVS lov = new M_LOVS();
lov.TITLE = masterData.Title;
lov.TYPE_ID = masterData.Type;
lov.IS_ACTIVE = masterData.IsActive ? 1 : 0;
lov.AMD_BY = addedBy;
lov.AMD_ON = DateTime.Now;
dbContext.M_LOVS.Add(lov);
dbContext.SaveChanges();

JPA: the better way of getting the first object in a list of ordered objects?

I need to retrieve the most recently updated object. Currently I am able to retrieve it by first doing something similar to the following:
em.createQuery("select m from MyObject m order by m.updateTime").setFirstResult(0).setMaxResults(1).getResultList()
and then getting the only object if the result list is not empty. I am curious whether there is any better way of doing this type of thing.
Thanks and regards.
Setting first result to 0 is redundant in this case and if you need just one row then you could use a getSingleResult() function.
So your code could be modified as follows:
MyObject myObject = em.createQuery("select m from MyObject m order by m.updateTime").setMaxResults(1).getSingleResult();
EDIT: as Tiny has mentioned in the comment in case when there are no matching rows the code will throw a NoResultException which is to be handled (e.g. assign a null value in this case).
EDIT2:
I've checked the Hibernate implementation of both methods and it turned out that getSingleResult() has all the code that getResultList() has and on top of that the following block:
if ( result.size() == 0 ) {
NoResultException nre = new NoResultException( "No entity found for query" );
getEntityManager().handlePersistenceException( nre );
throw nre;
}
else if ( result.size() > 1 ) {
final Set<X> uniqueResult = new HashSet<X>(result);
if ( uniqueResult.size() > 1 ) {
NonUniqueResultException nure = new NonUniqueResultException( "result returns more than one elements" );
getEntityManager().handlePersistenceException( nure );
throw nure;
}
else {
return uniqueResult.iterator().next();
}
}
else {
return result.get( 0 );
}
thus you end up with a slower implementation when using getSingleResult().
EDIT3: getSingleResult() would be beneficial in case if having zero or more than one resulting row is an invalid/exceptional data state (i.e. if such a case occurs then you know that your data is corrupted). Since both NoResultException and NonUniqueResultException are uncatched exceptions you will end up with only one line of code (no if, no catch needed in this case).

how to write native query in jpa

I am getting the following error when I press the search button:
An Error Occurred:
Exception [EclipseLink-4002] (Eclipse Persistence Services -
2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal
Exception: java.sql.SQLException: Missing IN or OUT parameter at
index:: 1 Error Code: 17041 Call: SELECT * FROM CRM_DAILY_SHEET WHERE
to_char(reported_on,'dd-MM-yy') = :reportedOn Query:
ReadAllQuery(referenceClass=CrmDailySheet sql="SELECT * FROM
CRM_DAILY_SHEET WHERE to_char(reported_on,'dd-MM-yy') = :reportedOn")
Code:
public List < CrmDailySheet > searchres() throws Exception {
SimpleDateFormat ddMMMyyFormat = new SimpleDateFormat("dd/MM/yy");
Date d1 = searchsht.getReportedOn();
String date_to_string = ddMMMyyFormat.format(d1);
return crmsrvc.searchDailysht(date_to_string);
}
try {
Query query = em.createNativeQuery("SELECT * FROM CRM_DAILY_SHEET
WHERE to_char (reported_on,'dd-MM-yy') = :reportedOn", CrmDailySheet.class);
query.setParameter("reportedOn", reportedOn);
List < CrmDailySheet > res = query.getResultList();
return res;
} finally {
em.close();
}
Can anyone find the solution please?
You are trying to use the JPQL parameter syntax (the ":reportedOn") with a native query. Try using ? instead and set the parameter value by position, e.g.:
Query query = em.createNativeQuery("SELECT * FROM CRM_DAILY_SHEET
WHERE to_char (reported_on,'dd-MM-yy') = ?", CrmDailySheet.class);
query.setParameter(1, reportedOn);

DB2DataAdapter.Fill(dataset) throws error "SQL0901N (Reason "CPF4273".) SQLSTATE=58004"

My application is Dot Net based.I am using VS My application uses IBm DB2 at its backend.
My Query is
SELECT A, B FROM SERVER.D WHERE A IN
(SELECT C FROM SERVER.E WHERE X = '01OBPP' AND Y= 'U' AND Z= '1')
A,B,C,X,Y,Z-COLUMN NAME, SERVER- SERVER NAME, D AND E -TABLE NAME
PFB the code-
DB2DataAdapter dbAdapter = null;
DB2Connection dbConn = null;
DB2Command dbCommand;
DataSet dsReturnDataSet ;
dbConn = new DB2Connection(connectionString);
if (dbConn.State == ConnectionState.Closed) dbConn.Open();
dsReturnDataSet.Clear();
dbCommand = GetCommand();
dbCommand.CommandText = queryString;
dbCommand.Connection = dbConn;
dbAdapter = new DB2DataAdapter((DB2Command)dbCommand);
dbAdapter.Fill(dsReturnDataSet);
return dsReturnDataSet;
The GetCommand() method has the following statement
DB2Command dbCommand;
dbCommand = null;
dbCommand = new DB2Command();
dbCommand.CommandType = CommandType.Text;
dbCommand.CommandTimeout = 30;
return dbCommand;
While it hits the line 'dbAdapter.Fill(dsReturnDataSet);' it stucks there for a very long time and after that it throws the error
"ERROR [58004] [IBM][AS] SQL0901N The SQL statement failed because of
a non-severe system error. Subsequent SQL statements can be processed.
(Reason "CPF4273".) SQLSTATE=58004"
Please provide some pointers.
i will be very grateful if any one can give some pointers as to hoW to solve this error.
Check your database log. There should be a db2diag.log file in the db2dump directory under the instance's sqllib directory. Search this file for the above error and it should contain the root cause (that non-severe system error) that it refers to.

Extending Zend_Db

I apologize if my title is a bit misleading and it turns out that it's some other class under Zend_Db.
I use the following method of extracting data from a MSSQL:
// $_config contains information about how to connect to my MSSQL server
$config = new Zend_Config($_config);
$db = Zend_Db::factory($config->database);
$sql = "SELECT * FROM table1";
print_r($db->fetchAll($sql));
So far no problem and everything runs smooth :).
Now I need to run some more complex queries with multiple rowsets:
$sql2 = <<<EOD
DECLARE #test INT
SET #test = 42
SELECT * FROM table1 WHERE col1 = #test
SELECT col2 FROM table2 UNION
SELECT col3 FROM table2
SELECT * FROM table3
EOD;
print_r($db->fetchAll($sql2));
I hope you get the idea.
Using $db->fetchAll($sql2); will result in
Fatal error: Uncaught exception
'Zend_Db_Statement_Exception' with
message 'SQLSTATE[HY000]: General
error: 10038 Attempt to initiate a new
SQL Server operation with results
pending. [10038] (severity 7)
[(null)]' in
\Sacp026a\sebamweb$\prod\includes\Zend\Db\Statement\Pdo.php:234
The following function will return all the correct rowsets:
function sqlquery_multiple($zdb, $sql) {
$stmt = $zdb->query($sql);
$rowsets = array();
do {
if ($stmt->columnCount() > 0) {
$rowsets[] = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
} while ($stmt->nextRowset());
return $rowsets;
}
print_r(sqlquery_multiple($db, $sql2));
Now my big question is:
How do I extend Zend_Db, so I can implement and use the function above as $db->fetchMulti($sql2); instead of sqlquery_multiple($db, $sql2)?
Thanks in advance :)
NB: It's worth mentioning that I'm using the ODBC-patch in order to be able to fetch multiple rowsets in the first place.