How to remove records with partial keys in ActivePivot - primary-key

I need to remove records from a store of ActivePivot 5.0.
How can I achieve this when I do not know the full keys of these records?

this should work fine:
try {
datastore.getTransactionManager().startTransaction();
datastore.getTransactionManager().removeWhere("storeName", BaseConditions.Equal("attribute", value));
datastore.getTransactionManager().commitTransaction();
} catch (DatastoreTransactionException e) {
try {
datastore.getTransactionManager().rollbackTransaction();
} catch (DatastoreTransactionException re) {
throw new QuartetRuntimeException("The transaction rollback has failed.", re);
}
throw new QuartetRuntimeException("The transaction commit has failed.", e);
}

Related

What does timeout operator measure in Reactor and why it doesn't work in some cases?

Recently, a reactive piece of code results in timeout, it involves redis operation, like this:
redisOps.entries(key).map(...).map(...).switchIfEmpty().timeout();
In order to identify if timeout happens in redis query, I think timeout should be located after entries, in this way, map consumed time would not be monitored by timeout. So I made a guess, and wrote demo.
does timeout monitor data emission elapsed time until it, and data operations after it is not counted? For example, in the following code snippet, only time consumption in a and b are monitored by timeout, not including c or d.
Mono mono = foo();
mono.a().b().timeout().c().d();
Why in the following code, timeout does not work.
Mono.just("good luck")
.map(s -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "timeout 1";
})
.map(s->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "timeout 2";
})
.timeout(Duration.ofSeconds(1))
.subscribe(System.out::println);
compared with item 2, timeout in the following code works:
public static void main(String[] args) {
Mono.fromCallable(() -> {
log.info("begin 1");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("return 1");
return "good luck 1";
})
.timeout(Duration.ofMillis(1500l))
.map((s) -> {
log.info("begin 2");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("return 2");
return "good luck 2";
})
.subscribe(System.out::println);
}
Anwser the comment's question, some operator is eager, it will execute at assembly stage. you can use some lazy operator, eg: defer、fromSupplier...
public Mono<?> defaultData() {
return Mono.defer(() -> {
//do Something
return ...
});
}
Here are some demo(https://github.com/echooymxq/reactive-study).

Why does SignalR recommend using finally to propagate errors in streams?

The SignalR docs on streaming state:
Wrap logic in a try ... catch statement. Complete the Channel in a finally block. If you want to flow an error, capture it inside the catch block and write it in the finally block.
They then proceed to give an example that goes through these convolutions for no apparent gain. Why is this? What difference does it make whether one captures an exception and completes the channel from the finally block versus completing then and there in the catch block?
Possibly to centralize the writer completion logic, even if takes just a single invocation - and you may want to insert additional related logic there (such as logging), if needed.
Exception localException = null;
try
{
// ...
}
catch (Exception ex)
{
localException = ex;
}
finally
{
writer.Complete(localException);
}
versus:
var completed = false;
try
{
// ...
}
catch (Exception ex)
{
writer.Complete(ex);
completed = true;
}
finally
{
if (!completed)
{
writer.Complete(null);
}
}

how am i supposed to pull a record from DAO vector?

I'm trying to implement the login page based on Oracle sql using JFrame(swing). I already have inserted IDs and PWs on database. Plus, I've also already defined appropriate -I think- LoginMember method in DAO. Below are the codes for Jframe page and DAO. Please let me know what is wrong with this. I've been struggling with this for the last 5 hours and still have no idea what to do.. HELP!! Sorry if you feel that I have not given enough info to solve this problem.
JButton btnLogin = new JButton("Login");
btnLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String strID=tfID.getText();
String strPW=String.valueOf(pwfPW.getPassword());
if(tfID.getText().equals("")) {
JOptionPane.showMessageDialog(Login.this, "Please type your ID");
} else {
dao=new M_DAO();
dao.loginMember(strID,strPW);
if(tfID.getText().equals(dao.loginMember(strID,strPW))) {
JOptionPane.showMessageDialog(Login.this, strID+" : successfully logged in");
}else if(strID ==null && strID.equals(strPW)){
JOptionPane.showMessageDialog(Login.this, "Incorrect ID or PW.");
}else{
System.out.println(10);
}
}
}
});
DAO:
public Vector loginMember(String strID,String strPW) {
Vector items=new Vector();
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
conn=DB.hrConn();
String sql="select * from member where strID=? and strPW=?";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "strID");
pstmt.setString(2, "strPW");
rs=pstmt.executeQuery();
if(rs.next()){
Vector row=new Vector();
row.add("strID");
row.add("strPW");
items.add(row);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(rs!=null) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(pstmt!=null) pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return items;
}
I wish it would work so bad...
It only shows the correct answer when I type nothing on ID and PW textfields, saying "Please type your ID". It prints out 10 when I type something on those.(just to check which line has an error.) Oh, please let me know if I need to specify something else!

Sql Notification Supported Isolation Levels for Transactions

I am running multiple inserts using transactions. I am using the SqlDependency class to let the client machine know when the server has been updated.
The problem I am having is that whenever I insert using a transaction, no matter what isolation level I set for the transaction, the SqlNotificationEventArgs returns e.Info as Isolation which indicates that I have the wrong isolation level set for that transactions (I think). When I insert without using a transaction, everything runs smoothly.
My questions is, what are the supported Isolation levels, if any, for transactions when using Sql Notification?
Below is some of the code I am using for the notification:
void DataChanged(object sender, SqlNotificationEventArgs e) {
var i = (ISynchronizeInvoke)_form;
if (i.InvokeRequired) {
var tempDelegate = new OnChangeEventHandler(DataChanged);
object[] args = { sender, e };
i.BeginInvoke(tempDelegate, args);
} else {
var dependency = (SqlDependency)sender;
if (e.Type == SqlNotificationType.Change) {
dependency.OnChange -= DataChanged;
GetData(dependency);
}
}
}
And for the transaction:
public void ExecuteNonQueryData(List<string> commandTexts) {
SqlConnection connection = null;
var command = new SqlCommand();
SqlTransaction transaction = null;
try {
connection = new SqlConnection(GetConnectionString());
connection.Open();
transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
foreach (var commandText in commandTexts) {
try {
command.Connection = connection;
command.CommandText = commandText;
command.Transaction = transaction;
command.ExecuteNonQuery();
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
transaction.Commit();
} catch (Exception ex) {
Console.WriteLine(ex.Message);
} finally {
command.Dispose();
if (transaction != null) transaction.Dispose();
if (connection != null) {
connection.Close();
connection.Dispose();
}
}
commandTexts.Clear();
}
Edit: I was committing the transaction in the wrong place.
Apparently Query Notification does not support transactions. Removing the transaction code fixed this problem.
According to Microsoft:
Transact-SQL does not provide a way to subscribe to notifications. The CLR data access classes hosted within SQL Server do not support query notifications.
This quote was found at http://msdn.microsoft.com/en-us/library/ms188669.aspx, which describes how Query Notifications work and their requirements.

Nhibernate: Handling an ITransaction Exception So That New Transactions Can Continue with same ISession

I have a list of 10 data objects that I want to insert/update to the database using NHibernate. If one throws an exception (say a primary key violation) I want to still insert/update the other 9. I rolled each object operation into its own atomic transaction, and roll back the transaction if there is an exception. Problem is that if a transaction does cause an exception and is rolled back, on the next transaction Nhibernate complains with the error: null id in Nexus.Data.PortfolioCorporateEntity entry (don't flush the Session after an exception occurs)
My main program is simple. It creates a session from a sessionfactory, creates the data access layer, does some work on the data objects and then tries to persist those data objects to the database.
sessionsManager = new NHibernateSessionManager();
session = sessionsManager.GetSession();
DALC = new NHibernateDataProvider(session);
…
foreach (var pce in pces)
{
try
{
DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce);
}
catch (Exception ex)
{
Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString());
}
}
This is the updateOrAdd procedure in my Nhibernate Data Access Layer, called 10 times for 10 objects.
public void UpdateOrAddObject<T>(T workObject)
{
using (ITransaction tx = mSession.BeginTransaction) {
try {
mSession.SaveOrUpdate(workObject);
mSession.Flush();
tx.Commit();
}
catch (Exception ex) {
tx.Rollback();
throw;
}
}
}
Just to make the point clear, the session is instantiated by the calling program and passed to the Data Access Layer object, constructor of which is below.
public NHibernateDataProvider(ISession session)
{
mSession = session;
}
This works fine except after the exception, it says don’t flush the session after exception. I’m not sure why – transaction was rolled back nicely and the database should be ready to accept another transaction no? What am I doing wrong?
It's not possible to re-use an NHibernate session after an exception is thrown. Quoting the documentation:
If the ISession throws an exception you should immediately rollback the
transaction, call ISession.Close() and discard the ISession instance.
Certain methods of ISession will not leave the session in a consistent state.
So the answer is that you can't do what you're trying to do. You need to create a new session and re-try the updates there.
I clear the session and it continues normally
ISession session = NHibernateHelper.Session;
using (ITransaction transaction = session.BeginTransaction())
{
try
{
session.Update(user, user.UserID);
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
session.Clear();
throw new DALException("Cannot update user", ex);
}
}
Thanks for the response. Just wanted to make sure it's done right. What you're saying is that my error handling should be simply changed to:
foreach (var pce in pces)
{
try
{
DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce);
}
catch (Exception ex)
{
Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString());
session.Close();
session = sessionsManager.GetSession();
DALC.Session = session;
}
}
Looks like this works just fine. Thanks.