Leniently handling conversion exceptions (skip/ignore) using mongo spring-data - mongodb

Was wondering if there's a way one can handle conversion errors in a lenient way.
Given a query that returns a List[ModelObject]
If there are 5 DBObjects retrieved, one of them is throwing a ConversionException when converted to ModelObject, is there a way to return the 4 convertible objects and provide a hook for the 1 conversion failure?

A bit late, but this answer might help someone else's search
I agree it would be nice to do this on a policy basis - at the moment, if you get a single conversion error, you get no list at all. I think there are use cases where this is a valid need.
However, since you can't, you need to register a custom converter for your ModelObject that converts leniently...
public class DBObjectToModelObjectConverter implements Converter<DBObject,ModelObject>{
public ModelObject convert(DBObject s) {
... Read from the DBObject into your ModelObject and work around the bad data
}
}
and then register this as a custom converter in your bean definitions. Something like:
<bean id="lenientModelReadConverter" class="com.my.DBObjectToModelObjectConverter"/>
<mongo:custom-converters>
<mongo:converter ref="lenientModelReadConverter"/>
</mongo:custom-converters>

Related

Pre-persistence validation for Scala case class using Salat/Casbah

Assuming that I have a Scala case class that is persisted using the Salat/Casbah/Mongo stack, I want to set up pre-persistence validation logic like I could easily do in Rails using ActiveRecord hooks or in Java using JSR 303 bean validation.
Perhaps there is a better way to think about this in a functional paradigm, but I want to accomplish something like the following:
case class SomeItem(
id: ObjectId = new ObjectId,
someProperty: String) {
#PrePersistence
def validate() = {
//perform some logic
//fail document save in certain conditions
}
}
I am having trouble finding any documentation on how to do something like this in Salat. I do see a #Persist annotation but it seems focused on serializing specific values and not creating hooks.
It seems like one option is to override the save method in the SalatDAO for my case class. Does anyone have an example of this or know of a better, built-in way to handle validation tied to a pre-persistence event?
Thanks!
Salat developer here.
Yes, #Persist is simply for ensuring that fields that aren't in the constructor are serialized - this is particularly useful for manipulating data in MongoDB. One example is where you want to ensure that all the fields are populated with a value so you can sort sensibly, but the value is an Option which may not be present.
Unfortunately, the Java driver doesn't offer lifecycle callbacks like the Ruby driver :(
But what you want should be easy enough to do. Please file an issue at https://github.com/novus/salat/issues and describe how you would like the validation to behave - we can start a discussion and I can try to get something in for you in the 1.9.2 release.

Serialize Function1 to database

I know it's not directly possible to serialize a function/anonymous class to the database but what are the alternatives? Do you know any useful approach to this?
To present my situation: I want to award a user "badges" based on his scores. So I have different types of badges that can be easily defined by extending this class:
class BadgeType(id:Long, name:String, detector:Function1[List[UserScore],Boolean])
The detector member is a function that walks the list of scores and return true if the User qualifies for a badge of this type.
The problem is that each time I want to add/edit/modify a badge type I need to edit the source code, recompile the whole thing and re-deploy the server. It would be much more useful if I could persist all BadgeType instances to a database. But how to do that?
The only thing that comes to mind is to have the body of the function as a script (ex: Groovy) that is evaluated at runtime.
Another approach (that does not involve a database) might be to have each badge type into a jar that I can somehow hot-deploy at runtime, which I guess is how a plugin-system might work.
What do you think?
My very brief advice is that if you want this to be truly data-driven, you need to implement a rules DSL and an interpreter. The rules are what get saved to the database, and the interpreter takes a rule instance and evaluates it against some context.
But that's overkill most of the time. You're better off having a little snippet of actual Scala code that implements the rule for each badge, give them unique IDs, then store the IDs in the database.
e.g.:
trait BadgeEval extends Function1[User,Boolean] {
def badgeId: Int
}
object Badge1234 extends BadgeEval {
def badgeId = 1234
def apply(user: User) = {
user.isSufficientlyAwesome // && ...
}
}
You can either have a big whitelist of BadgeEval instances:
val weDontNeedNoStinkingBadges = Map(
1234 -> Badge1234,
5678 -> Badge5678,
// ...
}
def evaluator(id: Int): Option[BadgeEval] = weDontNeedNoStinkingBadges.get(id)
def doesUserGetBadge(user: User, id: Int) = evaluator(id).map(_(user)).getOrElse(false)
... or if you want to keep them decoupled, use reflection:
def badgeEvalClass(id: Int) = Class.forName("com.example.badge.Badge" + id + "$").asInstanceOf[Class[BadgeEval]]
... and if you're interested in runtime pluggability, try the service provider pattern.
You can try and use Scala Continuations - they can give you the ability to serialize the computation and run it at later time or even on another machine.
Some links:
Continuations
What are Scala continuations and why use them?
Swarm - Concurrency with Scala Continuations
Serialization relates to data rather than methods. You cannot serialize functionality because it is a class file which is designed to serialize that and object serialization serializes the fields of an object.
So like Alex says, you need a rule engine.
Try this one if you want something fairly simple, which is string based, so you can serialize the rules as strings in a database or file:
http://blog.maxant.co.uk/pebble/2011/11/12/1321129560000.html
Using a DSL has the same problems unless you interpret or compile the code at runtime.

XML Serialization: object not serialized

I'm getting an "Unspecified error" when I try to call a particular web-service method. Using XMLSpy I discover that the parameter object just hasn't been serialized.
In the generated serializer source I note the lines:
if (!needType) {
System.Type t = o.GetType();
if (t == typeof(global::moonraker1.Conference)) {
}
else {
throw CreateUnknownTypeException(o);
}
}
However, the wsdl import had created a unit called moonraker1.BookingService, so the type of the parameter object is actually moonraker1.BookingService.Conference. It seems entirely possible that this is why the object isn't serialised, although I don't understand why the message still appears to be passed to the web service.
Please can anyone shed any light on this? Or am I on entirely the wrong track?
Now I'm not sure if this is it, but it looks like some .NET code.
Maybe the answer is as simple as you need to have a default constructor in your type.
My own experience from serialization in .NET is that most of the time it's just because I have written a custom constructor and then forgot to write a default constructor afterwards..

Derived Type with DateTime Condition

I have a Show table, and I would like to have a derived type called ActiveShow which only returns shows in the future
Show.ShowDateTime > DateTime.Now
Is there a way that I can achieve this using the designer or some other way so that creating an instance of ActiveShow will always adhere to the date condition?
Absolutely you could do this using a DefiningQuery (which is essentially a TSQL view) in the SSDL.
But I don't recommend it.
The problem is type memberships would be transient, when it should be permanent, or at the very least require you to explicitly change it.
I.e. you could end up in a situation where at one point something is an ActiveShow (and loaded in memory) but if you do a subsequent query you might attempt to load the same object as a Show. In this situation what would happen to identity resolution is anyone's guess.
This will more than likely resort in some very nasty unexpected side-effects.
As an alternative perhaps an extra Property in your Context added in a partial class:
i.e.
public partial class MyContext
{
public ObjectQuery<Show> ActiveShows
{
get{
return this.Shows.Where(s => ShowDateTime > DateTime.Now)
as ObjectQuery<Show>;
}
}
}
This probably gives you most of the benefits without most of the risks.
Hope this helps
Alex

generic type dependency injection: How to inject T

I want to handle different types of docs the same way in my application
Therefore:
I have a generic interface like this.
public interface IDocHandler<T>where T: class
{
T Document { get;set;}
void Load(T doc);
void Load(string PathToDoc);
void Execute();
void Execute(T doc);
}
And for different types of documents I implement this interface.
for example:
public class FinanceDocumentProcessor:IDocumentHandler<ReportDocument>
{}
public class MarketingDocumentProcessor:IDocumentHandler<MediaDocument>
{}
Then I can do of course something like this:
IDocumentHandler<ReportDocument> docProc= new FinanceDocumentProcessor();
It would be interessting to know how I could inject T at runtime to make the line above loosly coupled...
IDocumentHandler<ReportDocument> docProc = container.resolve("FinanceDocumentProcessor());
but I want to decide per Configuration wether I want to have my FinanceDomcumentProcessor or my MarketingDocumentProcessor... therefore I would have to inject T on the left site, too ...
Since I have to use c# 2.0 I can not use the magic word "var" which would help a lot in this case... but how can I design this to be open and flexible...
Sorry for the misunderstanding and thanks for all the comments but I have another example for my challenge (maybe I am using the wrong design for that) ...
But I give it a try: Same situation but different Explanation
Example Image I have:
ReportingService, Crystal, ListAndLabel
Three different Reporting Document types. I have a generic Handler IReportHandler<T> (would be the same as above) this Handler provides all the functionality for handling a report Document.
for Example
ChrystalReportHandler:IReportHandler<CrystalReportDocument>
Now I want to use a Framework like Unity (or some else framework) for dependency injection to decide via configuration whether I want to use Crystal, Reportingservices or List and Label.
When I specify my mapping I can inject my ChrystalReportHandler but how can I inject T on the left side or in better word The Type of ReportDocument.
IReportHandler<T (this needs also to be injected)> = IOContainer.Resolve(MyMappedType here)
my Problem is the left Site of course because it is coupled to the type but I have my mapping ... would it be possible to generate a object based on Mapping and assign the mapped type ? or basically inject T on the left side, too?
Or is this approach not suitable for this situation.
I think that with your current design, you are creating a "dependency" between IDocumentHandler and a specific Document (ReportDocument or MediaDocument) and so if you want to use IDocumentHandler<ReportDocument or MediaDocument> directly in your code you must assume that your container will give you just that. The container shouldn't be responsible for resolving the document type in this case.
Would you consider changing your design like this?
public interface IDocumentHandler
{
IDocument Document { get; set; }
void Load(IDocument doc);
void Load(string PathToDoc);
void Execute();
void Execute(IDocument doc);
}
public class IDocument { }
public class ReportDocument : IDocument { }
public class MediaDocument : IDocument { }
public class FinanceDocumentProcessor : IDocumentHandler { }
public class MarketingDocumentProcessor : IDocumentHandler { }
If I understand you correctly, you have two options.
if you have interface IDocHandler and multiple classes implementing it, you have to register each type explicitly, like this:
container.AddComponent>(typeof(FooHandler));
if you have one class DocHandler you can register with component using open generic type
container.AddComponent(typeof(IDocHandler<>), typeof(DocHandler<>));
then each time you resolve IDocHandler you will get an instance of DocHandler and when you resolve IDocHandler you'll get DocHandler
hope that helps
You need to use a non-generic interface on the left side.
Try:
public interface IDocumentHandler { }
public interface IDocumentHandler<T> : IDocumentHandler { }
This will create two interfaces. Put everything common, non-T-specific into the base interface, and everything else in the generic one.
Since the code that you want to resolve an object into, that you don't know the type of processor for, you couldn't call any of the T-specific code there anyway, so you wouldn't lose anything by using the non-generic interface.
Edit: I notice my answer has been downvoted. It would be nice if people downvoting things would leave a comment why they did so. I don't care about the reputation point, that's just minor noise at this point, but if there is something seriously wrong with the answer, then I'd like to know so that I can either delete the answer (if it's way off target) or correct it.
Now in this case I suspect that either the original questionee has downvoted it, and thus either haven't posted enough information, so that he's actually asking about something other than what he's asked about, or he didn't quite understand my answer, which is understandable since it was a bit short, or that someone who didn't understand it downvoted it, again for the same reason.
Now, to elaborate.
You can't inject anything "on the left side". That's not possible. That code have to compile, be correct, and be 100% "there" at compile-time. You can't say "we'll tell you what T is at runtime" for that part. It just isn't possible.
So the only thing you're left with is to remove the T altogether. Make the code that uses the dependency not depend on T, at all. Or, at the very least, use reflection to discover what T is and do things based on that knowledge.
That's all you can do. You can't make the code on the left side change itself depending on what you return from a method on the right side.
It isn't possible.
Hence my answer.