I am using JsonDocument inserted = bucket.insert(doc); on couchbase-server-enterprise_4.1.0-ubuntu14.04_amd64.
What exactly happening is, I trigger this insert command and on success of this I trigger the Select command on same document. This Select command doesn't returns the update entries instead returns the old ones only. When I am using debugger before Select (wait for some seconds after insert and then call Select) it works totally fine. So i think insert behaves in async manner, not sure.
Other thing i have checked is upsert instead of insert, it is also not working. However when I do bucket.replace(doc) and then call Select, it returns the updated results. I have tried explicitly using the bucket.async().insert(doc) and the using toBlocking().single() on it, this also fails.
Is the issue with insert/upsert or I am doing something wrong.
Below is some of my code snippet ::
#Override
public T save(T entity, String username) {
String id = generateId(entity);
JsonObject data = JsonObject.fromJson(getContent(entity));
data.removeKey(ID);
data.put(TYPE, klass.getSimpleName());
data.put(CREATED_AT, new Date().getTime());
data.put(CREATED_BY, username);
data.put(MODIFIED_AT, new Date().getTime());
data.put(MODIFIED_BY, username);
data.put(ACTIVE, true);
T persistedEntity = getEntity(bucket.insert(JsonDocument.create(id, data)));
return persistedEntity;
}
#Override
public List findAll() {
Statement query = selectAll().where(typeExpression()).orderBy(Sort.desc(x(CREATED_AT)));
return getEntities(query);
}
protected AsPath selectAll() {
return Select.select("meta().id, *").from(i(bucket.name()));
}
N1QL queries can run with varying degrees of consistencies, unlike key/value operations which are always consistent (you "read-your-own-writes").
So there is a slight delay between an insertion and the indexer catching up to it. If you execute a N1QL query by default it will return what's the current state of the indexer, so if it is still indexing your document you won't see the update.
Try executing the query with a ScanConsistency of REQUEST_PLUS, where you do the bucket().query(...):
N1qlQuery n1qlQuery = N1qlQuery.simple(
selectStatement, //that's the Statement query in your example
N1qlParams
.build()
.consistency(ScanConsistency.REQUEST_PLUS)
);
This will instruct N1QL to wait for the indexer to finish indexing pending mutations.
Related
I am in the process of converting an application from Jython to compiled Java. The application uses a host of SQL Server stored procedures to do CRUD operations. All of the procedures are defined with a return value that indicates status, and some output parameters used to provide feedback to the application. Most of the procedures also return a result set. I'm struggling with how to retrieve the return value and the result set and the output parameters.
I normally work with C# so the nuances of JDBC are new to me. I've been testing with one of the procedures that does an insert to the database and then does a select on the inserted object.
Here's a simplified example procedure just to use for the purpose of illustration. The actual procedures are more complex than this.
CREATE PROCEDURE [dbo].[sp_Thing_Add]
(
#Name NVARCHAR(50),
#Description NVARCHAR(100),
#ResultMessage NVARCHAR(200) = N'' OUTPUT
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #Result INT = -1
DECLARE #ResultMessage = 'Procedure incomplete'
BEGIN TRY
INSERT INTO Things (Name, Description) VALUES (#Name, #Description)
SELECT * FROM Things WHERE ThingID = SCOPE_IDENTITY()
END TRY
BEGIN CATCH
SELECT #Result = CASE WHEN ERROR_NUMBER() <> 0 THEN ERROR_NUMBER() ELSE 1 END,
#ResultMessage = ERROR_MESSAGE()
GOTO EXIT_SUB
END CATCH
SUCCESS:
SET #Result = 0
SET #ResultMessage = N'Procedure completed successfully'
RETURN #Result
EXIT_SUB:
IF #Result <> 0
BEGIN
-- Do some error handling stuff
END
RETURN #Result
I can successfully retrieve the ResultSet using the following code.
var conn = myConnectionProvider.getConnection();
String sql = "{? = call dbo.sp_Thing_Add(?, ?, ?)}"
call = conn.prepareCall(sql);
call.registerOutParameter(1, TYPES.Integer); // Return value
call.setString("Name", thing.getName());
call.setString("Description", thing.getDescription());
call.registerOutParameter("ResultMessage", TYPES.NVARCHAR);
ResultSet rs = call.executeQuery();
// Try to get the return value. This appears to close the ResultSet and prevents data retrieval.
//int returnValue = call.getInt(1);
// Normally there'd be a check here to make sure things executed properly,
// and if necessary the output parameter(s) may also be leveraged
if (rs.next()) {
thing.setId(rs.getLong("ThingID"));
// Other stuff actually happens here too...
}
If I try retrieving the return value using the line that's commented out, I get an error stating that the ResultSet is closed.
com.microsoft.sqlserver.jdbc.SQLServerException: The result set is closed.
I've been through the documentation and have seen how to do return values, output parameters, and result sets. But how can I leverage all 3?
Given the order of processing in your stored procedure (insert, select, then populate result parameters), you need to process the result set before you retrieve the return value with CallableStatement.getXXX.
The output is in the ResultSet rs retrieved from executeQuery().
You may want to use the excute method as such:
call.execute();
String returnValue = call.getString("ResultMessage");
You also want to map correctly to the output type.
Your connection got closed once the execute query is executed. Basically mysql jdbc connection extends to AutoCloseable implicitly. Since your result is only entity from procedure,please get the value by index 0 and do a proper index out of bound exception handling.
How to execute native query (create table) in java and also in return get information about is operation was successfull or not. Every method i did try always work the same. Query is working but i am getting errors about "how really bad that query was" but as i said it works.
try{
session.createNativeQuery("create table test (id number)").getResultList()
}
catch(Exception e){
// I am getting error "Could not extract result set metadata"
// Is there any way to execute getResultList() only if operation was select?
}
Summarizing, I need execute CRUD.
1. If "select" was executed i need resultList.
2. If "create" i don't want to execute getResultSet()
3. If "insert" was executed i need information about numbers of row affected.
etc... ... ...
And most important i always need information about eventual errors! If query had missing syntax or something i always need to get that information.
Guys can someone help me? I am fighting with this from several days...
A simple example using Native Query. You can determine the result of query from the affected rows value.
EntityTransaction entityTransaction;
EntityManager entityManager;
try
{
entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
// rowsUpdated - The number of "affected rows".
int rowsUpdated = entityManager.createNativeQuery("create table test (id nubmer)").executeUpdate();
entityTransaction.commit();
}
catch (HibernateException | IllegalStateException e)
{
// handle exceptions
if (entityTransaction != null && entityTransaction.isActive())
{
entityTransaction.rollback();
}
}
I am having trouble getting SELECT FOR UPDATE to work in Hibernate and Oracle.
When I have two threads with one EntityManager per thread, the second thread seems to be able to read the same row as the first. I can see this by adding traces which show that the second thread reads the same row while the first is in between query.getSingleResult() and entityManager.getTransaction().commit() My expectation was that once a SELECT FOR UPDATE has been issued no one else should be able to read the same row until it is committed by the first thread. But this is not happening.
I can resort to an alternative implementation. What I want to achieve is only one process being able to read and update a row in an Oracle table so that it behaves like a queue given that the consumer processes can be in different machines.
Here is the minimum example of my code:
public MyMessage getNextMessage() {
String sql = "SELECT * FROM MESSAGE WHERE MESSAGE_STATUS = 'Pending' AND rownum=1 FOR UPDATE OF MESSAGE_STATUS";
entityManager.getTransaction().begin();
Query query = entityManager.createNativeQuery(sql, MyMessage.class);
query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
MyMessage msg = null;
try {
msg = (MyMessage) query.getSingleResult();
} catch (NoResultException nodatafound) {
// Ignore when no data found, just return null
}
if (msg != null) {
msg.setMessageStatus("In Progress");
entityManager.persist(msg);
}
entityManager.getTransaction().commit();
return msg;
}
I have this select in PostgreSQL:
SELECT "field_1", "field_2","field_3", MIN(COALESCE(NULLIF("field_4",'') ,'TBD')) MINDP,MIN("field_5") MINBOD FROM "MY_TABLE" GROUP BY "field_1", "field_2","field_3"
And I want to use net.java.ao.Query to query my database. My function:
import net.java.ao.Query;
public List<myClass> find() {
String SQL = "SELECT \"field_1\", \"field_2\",\"field_3\", MIN(COALESCE(NULLIF(\"field_4\",'') ,'TBD')) MINDP,MIN(\"field_5\") MINBOD FROM \"MY_TABLE\" GROUP BY \"field_1\", \"field_2\",\"field_3\""
return newArrayList(ao.find(myClass.class, Query.select(SQL)));
}
The problem is: this code return all issues of my table.
When I run this SQL in postgreSQL console it works fine.
My code has different results than SQL console.
Does anybody know why is this happening?
Old question but if somebody steps over this -
Query.select() is not meant to put plain SQL into. It is more of a builder to create 'database independant' query. See some examples here: Finding entities
public MyEntity[] findMyEntities(String fieldValue) {
final Query query = Query.select()
.where("FIELD_VALUE = ?", fieldValue);
// evaluates to something like this
// SELECT * FROM MY_ENTITY WHERE FIELD_VALUE = x;
return ao.find(MyEntity.class, query);
}
This is why there's another method (which you used in your comment), that can handle plain SQL (findWithSQL).
Attention Query and find() often do not work as expected, so you might not get your original query to work using the query builder.
I am trying to query a table based on criteria from a join table using ORMLite.
Here is how I would express the query I am trying to write in tsql:
select * from media m inner join file f on m.fileId = f.fileId
where m.isNew = 1 OR f.isNew = 1
The result should be a list of media records where either the media record or the corresponding file record has isNew = 1.
I have read through the documentation on using OR in ORMLite, but all of the examples use a single table, not joining. Likewise I have read the documentation on joins, but none of the examples include a where clause that spans both tables. Is there any way besides a raw query to do this?
I had a look at this question: https://stackoverflow.com/a/12629645/874782 and it seems to ask the same thing, but the accepted answer produces an AND query, not an OR. Here is my code that I used to test that theory:
public List<Media> getNewMedia() {
Session session = getSession();
Account account = session.getSelectedAccount();
ContentGroup contentGroup = account.getSelectedContentGroup();
List<Media> results = null;
try {
QueryBuilder<Category, Integer> categoryQueryBuilder = getHelper().getCategoryDao().queryBuilder();
categoryQueryBuilder.where().eq("group_id", contentGroup.getId());
QueryBuilder<MediaCategory, Integer> mediaCatQb = getHelper().getMediaCategoryDao().queryBuilder();
mediaCatQb = mediaCatQb.join(categoryQueryBuilder);
QueryBuilder<FileRecord, Integer> fileQueryBuilder = getHelper().getFileDao().queryBuilder();
fileQueryBuilder.where().ge("lastUpdated", contentGroup.getLastDownload());
QueryBuilder<Media, Integer> mediaQb = getHelper().getMediaDao().queryBuilder();
mediaQb.where().eq("seen", false);
// join with the media query
results = mediaQb.join(fileQueryBuilder).join(mediaCatQb).query();
} catch (SQLException e) {
Log.e(TAG, "Sql Exception", e);
}
return results;
}
For the sake of completion, this is querying for a slightly more complex example than the one I gave above, this one expressed in tsql would be
select * from Media m join FileRecord f on m.fileRecordId = f.fileRecordId
where m.seen = false OR f.lastUpdated >= lastUpdateDate
When I run it, it is actually doing an AND query, which is what I would expect based on two joins with independent where clauses.
I think the key issue is that a where clause is inherently tied to a table, because it is performed on a QueryBuilder object which comes from a Dao that is specific to that table. How can I get around this?
I think what you are looking for is joinOr search for it in the ORMLite docs.
Like join(QueryBuilder) but this combines the WHERE statements of two
query builders with a SQL "OR".