Make DB calls through different models atomic - scala

Let's say that there are two models, Model1 and Model2, each model has a set of basic methods that call DB to retrieve or write data. For one Model1 there can exist multiple Model2, when inserting a (Model1, List[Model2]) all this data comes from the same form. The current implementation does the following:
Insert the Model1 instance using Model1's insert method.
When Model1 has been correctly inserted, proceed with inserting the List[Model2] using Model2's insert method.
The issue is that if an issue occurs while inserting one of the Model2, Model1 will remain in DB. A solution would be to catch any exception that anorm throws and undo whatever was executed before by doing the exact opposite of it. But is there a solution already out there that can be used? Something that captures all DB calls that were executed and revert them if needed?

What you're looking for is DB.withTransaction. It works exactly the same as DB.withConnection, except that autocommit is set to false, so that if any exceptions are thrown, the entire transaction will be rolled back.
Example:
case class Model1(id: Long, something: String, children: List[Model2])
case class Model2(id: Long, name: String)
object Model1 {
def create(model: Model1): Option[Model1] = {
DB.withTransaction { implicit c =>
SQL(...).executeInsert().map { id =>
model.copy(
id = id,
children = Model2.create(model.children)
)
}
}
}
}
object Model2 {
def create(models: List[Model2])(implicit c: java.sql.Connection): List[Model2] = {
...
}
}
Note how Model2.create accepts an implicit Connection parameter. This is so that it will use the same Connection as the Model1.create transaction, and be allowed to roll back on failure. I've left out the fine implementation details, as the key is just using withTransaction, and running each query on the same Connection.

Related

How to store override method in a variable in Scala

Here is My Code Snippet
package SimpleDruidOperation
import java.sql.{Connection, Driver, DriverManager, SQLException, Statement}
class ConnectionEstablishment {
var conn:Connection=_
var dr:Driver=_
def connEstablishment() =
{
try {
dr = new com.mysql.jdbc.Driver()
DriverManager.registerDriver(dr)
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/deven","root","root")
if(conn!=null)
println("!!Database Connected Succesfully!!!")
else
println("!!Check your Database Connection !!")
}
catch
{
case e:SQLException=>println("Exception is "+e.getMessage)
}
finally
{
conn.close()
}
}
}
class InsertintoDatabase extends ConnectionEstablishment {
var stmt:Statement=_
// override def connEstablishment():co = super.connEstablishment()
val conn:Connection=connEstablishment()//it is not going to override
def insertintoDatabase(): Unit =
{
println("Checking Conection Establishment")
try {
stmt = conn1.createStatement()
var sql = "insert into emp (eid,ename,eadd,emob) values (101,'Mohit','Pune',9156369938) "
var i = stmt.executeUpdate(sql)
if (i > 0)
println(i + "Value Inserted Successfully into Databaes")
else
println("!!Not Inserted Check something is going wrong!!")
}
catch
{
case e:SQLException=>println("Exception is "+e.getMessage)
}
finally
{
println("Closing Connection Establishment "+conn1.close())
println("CLosing Statement Connection "+conn1.close())
}
}
}
How to store override method in a variable in Scala
Here in my first class ConnectionEstablishment this class is to make connection and second class is for insert into database but the problem is I am unable to override the connEstablisment method because if I want override it then I am unable to establish a connection for insert
because I need it, so that i can call statement stmt=conn,createStatement().
How can I do it?
The problem here is that you have created a class hierarchy when you actually need two separate classes. The ConnectionEstablishment class represents a database connection and the InsertintoDatabase class represents an operation on that database, and there is no natural hierarchy between them.
Class hierarchies should have an "is a" relationship: If D inherits from C then it should make sense to say that a D is a C. So it makes sense for Circle to inherit from Shape because a circle is a shape. It does not make sense for a database operation to inherit from a database connection because a database operation is not a database connection.
A database operation needs a database connection, and this is a containment relationship, not a hierarchy.
So you should have a ConnectionEstablishment class that creates and manages the database connection, and an InsertintoDatabase class that takes a ConnectionEstablishment instance and uses it to insert items into the database.
With this arrangement you can create different subclasses of ConnectionEstablishment that connect to the database in different ways, and the InsertintoDatabase class will work with any of those subclasses. Likewise you can create new classes that use the database connection, such as DeleteFromDatabase, without having to inherit from the existing InsertintoDatabase class.

Mapper's toForm method does nothing on submit?

I have a very simple snippet to add a new row to the books table in the database:
def add = Book.toForm(Full("Add"), { _.save })
Calling this snippet in my template generates a form just fine, and submitting the form gives me a post request, but nothing happens, it never tries to talk to the database, no errors or exceptions occur:
09:03:53.631 [865021464#qtp-2111575312-18] INFO net.liftweb.util.TimeHelpers - Service request (POST) /books/ returned 200, took 531 Milliseconds
I am not sure if my model's save method is just not being called, or if the save method is not working. Based on examples in the book "Lift in Action", I am under the impression that the default Mapper save method should just work, and that is what I am using right now. My model class is simply:
class Book extends LongKeyedMapper[Book] with IdPK {
def getSingleton = Book
object name extends MappedString(this, 100)
}
object Book extends Book with LongKeyedMetaMapper[Book] {
override def dbTableName = "books"
}
Am I missing something in my model, or does this appear to be correct? If this should work, how do I debug it not working?
Forms don't work if you don't have a session (so you need cookies enabled). The session maps the form name to a function on the server. Unfortunately, lift doesn't log an error when the form's handler function isn't found.

Wicket - Wrapped collection Model "transformation"

I have a domain object which has a collection of primitive values, which represent the primary keys of another domain object ("Person").
I have a Wicket component that takes IModel<List<Person>>, and allows you to view, remove, and add Persons to the list.
I would like to write a wrapper which implements IModel<List<Person>>, but which is backed by a PropertyModel<List<Long>> from the original domain object.
View-only is easy (Scala syntax for brevity):
class PersonModel(wrappedModel: IModel[List[Long]]) extends LoadableDetachableModel[List[Person]] {
#SpringBean dao: PersonDao =_
def load: List[Person] = {
// Returns a collection of Persons for each id
wrappedModel.getObject().map { id: Long =>
dao.getPerson(id)
}
}
}
But how might I write this to allow for adding and removing from the original List of Longs?
Or is a Model not the best place to do this translation?
Thanks!
You can do something like this:
class PersonModel extends Model<List<Person>> {
private transient List<Person> cache;
private IModel<List<String>> idModel;
public PersonModel( IModel<List<String>> idModel ) {
this.idModel = idModel;
}
public List<Person> getObject() {
if ( cache == null ) {
cache = convertIdsToPersons( idModel.getObject() );
return cache;
}
public void setObject( List<Person> ob ) {
cache = null;
idModel.setObject( convertPersonsToIds( ob ) );
}
}
This isn't very good code but it shows the general idea. One thing you need to consider is how this whole thing will be serialised between requests, you might be better off extending LoadableDetachableModel instead.
Another thing is the cache: it's there to avoid having to convert the list every time getObject() is called within a request. You may or may not need it in practice (depends on a lot of factors, including the speed of the conversion), but if you use it, it means that if something else is modifying the underlying collection, the changes may not be picked up by this model.
I'm not quite sure I understand your question and I don't understand the syntax of Scala.
But, to remove an entity from a list, you can provide a link that simply removes it using your dao. You must be using a repeater to populate your Person list so each repeater entry will have its own Model which can be passed to the deletion link.
Take a look at this Wicket example that uses a link with a repeater to select a contact. You just need to adapt it to delete your Person instead of selecting it.
As for modifying the original list of Longs, you can use the ListView.removeLink() method to get a link component that removes an entry from the backing list.

EF Code First - Recreate Database If Model Changes

I'm currently working on a project which is using EF Code First with POCOs. I have 5 POCOs that so far depends on the POCO "User".
The POCO "User" should refer to my already existing MemberShip table "aspnet_Users" (which I map it to in the OnModelCreating method of the DbContext).
The problem is that I want to take advantage of the "Recreate Database If Model changes" feature as Scott Gu shows at: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx - What the feature basically does is to recreate the database as soon as it sees any changes in my POCOs. What I want it to do is to Recreate the database but to somehow NOT delete the whole Database so that aspnet_Users is still alive. However it seems impossible as it either makes a whole new Database or replaces the current one with..
So my question is: Am I doomed to define my database tables by hand, or can I somehow merge my POCOs into my current database and still take use of the feature without wipeing it all?
As of EF Code First in CTP5, this is not possible. Code First will drop and create your database or it does not touch it at all. I think in your case, you should manually create your full database and then try to come up with an object model that matches the DB.
That said, EF team is actively working on the feature that you are looking for: altering the database instead of recreating it:
Code First Database Evolution (aka Migrations)
I was just able to do this in EF 4.1 with the following considerations:
CodeFirst
DropCreateDatabaseAlways
keeping the same connection string and database name
The database is still deleted and recreated - it has to be to for the schema to reflect your model changes -- but your data remains intact.
Here's how: you read your database into your in-memory POCO objects, and then after the POCO objects have successfully made it into memory, you then let EF drop and recreate the database. Here is an example
public class NorthwindDbContextInitializer : DropCreateDatabaseAlways<NorthindDbContext> {
/// <summary>
/// Connection from which to ead the data from, to insert into the new database.
/// Not the same connection instance as the DbContext, but may have the same connection string.
/// </summary>
DbConnection connection;
Dictionary<Tuple<PropertyInfo,Type>, System.Collections.IEnumerable> map;
public NorthwindDbContextInitializer(DbConnection connection, Dictionary<Tuple<PropertyInfo, Type>, System.Collections.IEnumerable> map = null) {
this.connection = connection;
this.map = map ?? ReadDataIntoMemory();
}
//read data into memory BEFORE database is dropped
Dictionary<Tuple<PropertyInfo, Type>, System.Collections.IEnumerable> ReadDataIntoMemory() {
Dictionary<Tuple<PropertyInfo,Type>, System.Collections.IEnumerable> map = new Dictionary<Tuple<PropertyInfo,Type>,System.Collections.IEnumerable>();
switch (connection.State) {
case System.Data.ConnectionState.Closed:
connection.Open();
break;
}
using (this.connection) {
var metaquery = from p in typeof(NorthindDbContext).GetProperties().Where(p => p.PropertyType.IsGenericType)
let elementType = p.PropertyType.GetGenericArguments()[0]
let dbsetType = typeof(DbSet<>).MakeGenericType(elementType)
where dbsetType.IsAssignableFrom(p.PropertyType)
select new Tuple<PropertyInfo, Type>(p, elementType);
foreach (var tuple in metaquery) {
map.Add(tuple, ExecuteReader(tuple));
}
this.connection.Close();
Database.Delete(this.connection);//call explicitly or else if you let the framework do this implicitly, it will complain the connection is in use.
}
return map;
}
protected override void Seed(NorthindDbContext context) {
foreach (var keyvalue in this.map) {
foreach (var obj in (System.Collections.IEnumerable)keyvalue.Value) {
PropertyInfo p = keyvalue.Key.Item1;
dynamic dbset = p.GetValue(context, null);
dbset.Add(((dynamic)obj));
}
}
context.SaveChanges();
base.Seed(context);
}
System.Collections.IEnumerable ExecuteReader(Tuple<PropertyInfo, Type> tuple) {
DbCommand cmd = this.connection.CreateCommand();
cmd.CommandText = string.Format("select * from [dbo].[{0}]", tuple.Item2.Name);
DbDataReader reader = cmd.ExecuteReader();
using (reader) {
ConstructorInfo ctor = typeof(Test.ObjectReader<>).MakeGenericType(tuple.Item2)
.GetConstructors()[0];
ParameterExpression p = Expression.Parameter(typeof(DbDataReader));
LambdaExpression newlambda = Expression.Lambda(Expression.New(ctor, p), p);
System.Collections.IEnumerable objreader = (System.Collections.IEnumerable)newlambda.Compile().DynamicInvoke(reader);
MethodCallExpression toArray = Expression.Call(typeof(Enumerable),
"ToArray",
new Type[] { tuple.Item2 },
Expression.Constant(objreader));
LambdaExpression lambda = Expression.Lambda(toArray, Expression.Parameter(typeof(IEnumerable<>).MakeGenericType(tuple.Item2)));
var array = (System.Collections.IEnumerable)lambda.Compile().DynamicInvoke(new object[] { objreader });
return array;
}
}
}
This example relies on a ObjectReader class which you can find here if you need it.
I wouldn't bother with the blog articles, read the documentation.
Finally, I would still suggest you always back up your database before running the initialization. (e.g. if the Seed method throws an exception, all your data is in memory, so you risk your data being lost once the program terminates.) A model change isn't exactly an afterthought action anyway, so be sure to back your data up.
One thing you might consider is to use a 'disconnected' foreign key. You can leave the ASPNETDB alone and just reference the user in your DB using the User key (guid). You can access the logged in user as follows:
MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
And then use the User's key as a FK in your DB:
Guid UserId = (Guid) currentUser.ProviderUserKey ;
This approach decouples your DB with the ASPNETDB and associated provider architecturally. However, operationally, the data will of course be loosely connected since the IDs will be in each DB. Note also there will be no referential constraints, whcih may or may not be an issue for you.

MSTest with Moq - DAL setup

I'm new to Moq, and just started on a project that's already in development. I'm responsible for setting up unit testing. There's a custom class for the DatabaseFactory that uses EnterpriseLibrary and looks like this:
public Database CreateCommonDatabase()
{
return CreateDatabaseInstance(string.Empty);
}
private static Database CreateDatabaseInstance(string foo)
{
var database = clientCode == string.Empty
? DatabaseFactory.CreateDatabase("COMMON")
: new OracleDatabase(new ClientConnections().GetConnectionString(foo)));
return database;
}
Now, here's where that gets used (ResultData is another class of the type DataSet):
public ResultData GetNotifications(string foo, string foo2, Database database)
{
var errMsg = string.Empty;
var retval = 0;
var ds = new DataSet();
var sqlClause =
#"[Some SELECT statement here that uses foo]";
DbCommand cm = database.GetSqlStringCommand(sqlClause);
cm.CommandType = CommandType.Text;
// Add Parameters
if (userSeq != string.Empty)
{
database.AddInParameter(cm, ":foo2", DbType.String, foo2);
}
try
{
ds = database.ExecuteDataSet(cm);
}
catch (Exception ex)
{
retval = -99;
errMsg = ex.Message;
}
return new ResultData(ds, retval, errMsg);
}
Now, originally, the Database wasn't passed in as a parameter, but the method was creating a new instance of the DatabaseFactory using the CreateCommonDatabase method, and using it from there. However, that leaves the class untestable because I can't keep it from actually hitting the database. So, I went with Dependency Injection, and pass the Database in.
Now, I'm stuck, because there's no way to mock Database in order to test GetNotifications. I'm wondering if I'm overly complicating things, or if I'm missing something. Am I doing this the right way, or should I be rethinking how I've got this set up?
Edit to add more info*****
I really don't want to test the database. I want the Data.Notifications class (above) to return an instance of ResultData, but that's all I really want to test. If I go a level up, to the Business layer, I have this:
public DataSet GetNotifications(string foo, string foo1, out int returnValue, out string errorMessage, Database database)
{
ResultData rd = new data.Notifications().GetNotifications(foo, foo1, database);
returnValue = rd.ResultValue;
errorMessage = rd.ErrorMessage;
return rd.DataReturned;
}
So, originally, the database wasn't passed in, it was the Data.Notifications class that created it - but then again, if I left it that way, I couldn't help but hit the database to test this Business layer object. I modified all of the code to pass the Database in (which gets created a the web's Base page), but now I'm just not certain what to do next. I thought I was one unit test away from having this resolved, but apparently, either I'm wrong or I've got a mental roadblock to the right path.
You should be able to create a mock Database object if the methods in it are virtual. If they are not, then you have a little bit of a problem.
I don't know what type "Database" is, but you have a few options.
If you own the source code to Database, I would recommend extracting an interface IDatabase, rather than dealing with a Database class type. This will eliminate some complexity and give you something extremely testable.
If you don't have access to the Database class, you can always solve this with another layer of abstraction. Many people in this case use a Repository pattern that wraps the data access layer. Generally speaking in this case, most people leave testing Respository classes to integration tests (tests without any isolation), rather than unit tests.
Here's how you'd setup your test using option #1:
[TestMethod]
public void GetNotifications_PassedNullFoo_ReturnsData()
{
//Arrange
Mock<IDatabase> mockDB = new Mock<IDatabase>();
mockDB.Setup(db => db.ExecuteDataSet()).Returns(new DataSet() ... );
//Act
FooClass target = new fooClass();
var result = target.GetNotifications(null, "Foo2", mockDB.Object);
//Assert
Assert.IsTrue(result.DataSet.Rows.Count > 0);
}
My dataset code is a little rusty, but hopefully this gives you the general idea.
Based on the code you've given, I would think you would want to talk to the database, and not a mocked version.
The reason is that your GetNotifications code contains DB-specific instructions, and you'll want those to pass validation at the DB Engine level. So just pass in a Database that is connected to your test DB instance.
If you took the testing abstraction to a higher level, where you built unit tests for the database call and a version of this test that used a mocked database, you'd still have to run integration tests, which ends up being triple the work for the same amount of code coverage. In my opinion, it's far more efficient to do an integration test at tier borders you control then to write unit tests for both sides of the contract and integration tests.