subsonic 3 - The operation is not valid for the state of the transaction - subsonic3

I'm trying the following code
UserDetail ud = UserDetail.SingleOrDefault(u => u.UserName == CurrentUserName);
if (ud == null)
ud = new UserDetail();
Address uAddress = ud.AddressId.HasValue
? Address.SingleOrNew(a => a.Id == ud.AddressId)
: new Address();
using (TransactionScope tc = new TransactionScope())
{
uAddress.Save();
ud.AddressId = uAddress.Id;
ud.Save(); // error is here
tc.Complete();
}
when i reach ud.save() i get the error 'The operation is not valid for the state of the transaction. ---> System.Transactions.TransactionPromotionException: Failure while attempting to promote transaction'
if i comment out the transaction part it works fine, isn't .SingleOrDefault disconnecting from the db ?
thanks

You need to wrap your TransactionScope in a SharedDbConnectionScope, see here for details. The following should work for your example
using (SharedDbConnectionScope sharedConnectionScope = new SharedDbConnectionScope()){
{
using (TransactionScope tc = new TransactionScope())
{
uAddress.Save();
ud.AddressId = uAddress.Id;
ud.Save(); // error is here
tc.Complete();
}
}

it's a bug with subsonic 3.0.0.3
the fix can be found here issue 69

Related

Salesforce Apex unit testing error

I am trying to create a Salesforce unit test for a new trigger I created.
trigger SOSCreateCaseCustom on SOSSession (before insert) {
List<Event> aplist = new List<Event>();
List<SOSSession> sosSess = Trigger.new;
for (SOSSession s : sosSess) {
try {
Case caseToAdd = new Case();
caseToAdd.Subject = 'SOS Video Chat';
if (s.ContactId != null) {
caseToAdd.ContactId = s.ContactId;
} else {
List<Contact> contactInfo = [SELECT Id from Contact WHERE Email = :s.AppVersion];
if (!contactInfo.isEmpty()) {
caseToAdd.ContactId = contactInfo[0].Id;
s.ContactId = contactInfo[0].Id;
}
}
insert caseToAdd; s.CaseId = caseToAdd.Id;
}catch(Exception e){}
}
}
Here is my unit test:
#isTest
private class SOSCreateCaseCustomTest {
static testMethod void validateSOSCreateCase() {
String caseSubject = 'SOS Video Chat';
// set up case to add
SOSSession s = new SOSSession();
insert s;
Case caseToAdd = new Case(Subject='SOS Video Chat');
caseToAdd.ContactId = s.ContactId;
insert caseToAdd;
Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
// Test that escaltion trigger correctly escalate the question to a case
System.assertEquals(s.ContactId, ca.ContactId);
}
}
I keep getting this error.
System.QueryException: List has more than 1 row for assignment to SObject
I am new to Apex and I have no idea how to fix this. Any Salesforce and Apex experts out there who can help? Thanks!
I think this one:
Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
Because the casSubject may query more then one Case.... You should use List
The following line is causing issue :
Case ca = [SELECT Subject, ContactId from Case where Subject =: caseSubject];
It is returning two cases, the one you inserted in test data and other that is inserted by trigger. So it is having two records for Subject 'SOS Video Chat';
If you change the Subject from 'SOS Video Chat' to any other String it will run successfully.

AWS Device Farm CreateDevicePool internal error

I am trying to create device pool for a project using AWS DeviceFarm sdk in C#. I use the following command:
var createDevicePoolResponse = client.CreateDevicePool (new CreateDevicePoolRequest {
Name = "CustomDevicePool",
ProjectArn = projectArn,
Rules = new List<Rule> {
new Rule {
Attribute = DeviceAttribute.ARN,
Operator = RuleOperator.EQUALS_TO,
Value = "arn:aws:devicefarm:us-west-2::device:577DC08D6B964346B86610CFF090CD59"
}
}
});
It thinks for about a minute then I receive the following exception:
Error making request with Error Code InternalFailure and Http Status
Code InternalServerError. No further error information was returned by
the service.
ProjectArn is valid. I also tried different rules and get the same error every time.
Figured it out. Value needs to be surrounded with square brackets like so
var createDevicePoolResponse = client.CreateDevicePool (new CreateDevicePoolRequest {
Name = "CustomDevicePool",
ProjectArn = projectArn,
Rules = new List<Rule> {
new Rule {
Attribute = DeviceAttribute.ARN,
Operator = RuleOperator.IN,
Value = "[\"arn:aws:devicefarm:us-west-2::device:D45C750161314335924CE0B9B7D2558E\"]"
}
}
});

What Causes DynamoDB UpdateItem to Giv Fatal Error in Swift?

I am using Swift to let my app update an item on DynamoDB. I followed the example https://github.com/aws/aws-sdk-ios/blob/master/AWSiOSSDKTests/AWSDynamoDBTests.m#L244, the "- (void)testUpdateItem" method. My codes are as follows:
var dynamoDB = AWSDynamoDB()
var hashValue: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
hashValue.S = userID
var updatedValue: AWSDynamoDBAttributeValue = AWSDynamoDBAttributeValue()
updatedValue.S = updatedContent
var updateInput: AWSDynamoDBUpdateItemInput = AWSDynamoDBUpdateItemInput()
updateInput.tableName = kAWSDynamoDBMoEndpointARNTableName
updateInput.key = ["UserID": hashValue]
var valueUpdate: AWSDynamoDBAttributeValueUpdate = AWSDynamoDBAttributeValueUpdate()
valueUpdate.value = updatedValue
valueUpdate.action = AWSDynamoDBAttributeAction.Put
updateInput.attributeUpdates = ["Updated": valueUpdate]
updateInput.returnValues = AWSDynamoDBReturnValue.UpdatedNew
dynamoDB.updateItem(updateInput).waitUntilFinished()
However, as I run the codes, it always returns fatal error: unexpectedly found nil while unwrapping an Optional value. Looking into the error, I can find it is from Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.Uint) -> () with Thread 1: EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xe7ffdefe)
I didn't use .continueWithBlock or .continueWithSuccessBlock cuz neither helps to catch the error.
Any idea why? THANKS
You need to get an instance of AWSDynamoDB as follows:
let dynamoDB = AWSDynamoDB.defaultDynamoDB()
You are using the default - init method without any parameter, and it causes AWSDynamoDB instance to have no AWSServiceConfiguration.
With the current AWS, found that this worked well for posting the updateItem in Swift.
dynamoDB.updateItem(updateInput) .continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: { (task:AWSTask!) -> AnyObject! in
if (task.error == nil) {
log.debug("task.error == nil")
}
return nil
})
// instead of
dynamoDB.updateItem(updateInput).waitUntilFinished()

Subsonic 3 Save() then Update()?

I need to get the primary key for a row and then insert it into one of the other columns in a string.
So I've tried to do it something like this:
newsObj = new news();
newsObj.name = "test"
newsObj.Save();
newsObj.url = String.Format("blah.aspx?p={0}",newsObj.col_id);
newsObj.Save();
But it doesn't treat it as the same data object so newsObj.col_id always comes back as a zero. Is there another way of doing this? I tried this on another page and to get it to work I had to set newsObj.SetIsLoaded(true);
This is the actual block of code:
page p;
if (pageId > 0)
p = new page(ps => ps.page_id == pageId);
else
p = new page();
if (publish)
p.page_published = 1;
if (User.IsInRole("administrator"))
p.page_approved = 1;
p.page_section = staticParent.page_section;
p.page_name = PageName.Text;
p.page_parent = parentPageId;
p.page_last_modified_date = DateTime.Now;
p.page_last_modified_by = (Guid)Membership.GetUser().ProviderUserKey;
p.Add();
string urlString = String.Empty;
if (parentPageId > 0)
{
urlString = Regex.Replace(staticParent.page_url, "(.aspx).*$", "$1"); // We just want the static page URL (blah.aspx)
p.page_url = String.Format("{0}?p={1}", urlString, p.page_id);
}
p.Save();
If I hover the p.Save(); I can see the correct values in the object but the DB is never updated and there is no exception.
Thanks!
I faced the same problem with that :
po oPo = new po();
oPo.name ="test";
oPo.save(); //till now it works.
oPo.name = "test2";
oPo.save(); //not really working, it's not saving the data since isLoaded is set to false
and the columns are not considered dirty.
it's a bug in the ActiveRecord.tt for version 3.0.0.3.
In the method public void Add(IDataProvider provider)
immediately after SetIsNew(false);
there should be : SetIsLoaded(true);
the reason why the save is not working the second time is because the object can't get dirty if it is not loaded. By adding the SetIsLoaded(true) in the ActiveRecord.tt, when you are going to do run custom tool, it's gonna regenerate the .cs perfectly.

Subsonic 3 Simple Repository And Transactions

So this is what I have so far. Am I doing something wrong or is there a bug in 3.0.0.3?
var Repository = new SimpleRepository("DBConnectionName");
using (TransactionScope ts = new TransactionScope())
{
using (SharedDbConnectionScope scs = new SharedDbConnectionScope("connstring", "providerName"))
{
try
{
for (int i = 0; i < 5; i++)
{
Supplier s = new Supplier();
s.SupplierCode = i.ToString();
s.SupplierName = i.ToString();
Repository.Add<Supplier>(s);
}
ts.Complete();
}
catch
{
}
}
}
I'm getting an error in SubSonic DbDataProvider
public DbConnection CurrentSharedConnection
{
get { return __sharedConnection; }
protected set
{
if(value == null)
{
__sharedConnection.Dispose();
etc..
__sharedConnection == null :( Object Null Reference Exception :(
Finally solved this for myself. All of the above code does not work for me (SubSonic 3.0.0.3, using SQLite) but adding BeginTransaction() caused it to work as expected, greatly speeding up the transaction and rolling back the updates if any exceptions occur.
using (SharedDbConnectionScope sharedConnectionScope = new SharedDbConnectionScope(Access.Provider))
{
using (IDbTransaction ts = sharedConnectionScope.CurrentConnection.BeginTransaction())
{
IRepository repo = new SimpleRepository(Access.Provider);
//Do your database updates
//throw new ApplicationException("Uncomment this and see if the updates get rolled back");
ts.Commit();
}
}
For completeness: Access.Provider is a static property in a helper class for me that returns return SubSonic.DataProviders.ProviderFactory.GetProvider(ConnectionString, "System.Data.SQLite");
Perhaps switching the SharedDbConnectionScope and TransactionScope around may help.
using (SharedDbConnectionScope scs = new SharedDbConnectionScope("connstring", "providerName"))
{
using (TransactionScope ts = new TransactionScope())
{
}
}
This will happen when Migration is set - On tablemigration the dbconnection will be closed.
Try the SimpleRepository with SimpleRepositoryOptions.None.
Don't know if this is a bug. I think the transactions don't work with SimpleRepository, I've always half of the data saved when throwing an exception in the transaction... perhaps it's only for ActiveRecord? Anybody knows?