Why is my IQueryable LINQtoObject being treated as LINQtoSQL and throwing no supported translation to SQL - iqueryable

I have a LINQ dbml class that I am wrapping in a POCO. I have built overloaded constructors that take the DBML class and init. the wrapper objects properties based on the dbml object passed in.
For example
public class MyPerson{
public MyPerson(DBMLPerson p)
{
this.ID = p.ID;
this.Name = p.Name;
}
}
if I then do something like this where I return an IQueryable
{
return from p in datacontext.DBMLPerson
select new MyPerson(p){};
}
When I try to do further queries on that Iquearble I get "System.NotSupportedException: The member 'MyPerson.ID' has no supported translation to SQL.."
However if I do this
{
return from p in datacontext.DBMLPerson
select new MyPerson(){
ID = p.ID;
Name = p.Name;
};
}
I don't get an error at all and everything works perfect. Basically I want to have my class handle the conversion from LINQ object to POCO itself.
Basically I have to use the Object Initializer or I am unable to match on that field.

Ok not sure this will actually help anyone but but myself but my whole problem is the I shouldn't be using IQuerable after a certain point(outside of my repository)
iqueryable-can-kill-your-dog-steal-your-wife-kill-your-will-to-live-etc

Related

Spock - How to work with repeated interactions

For few test cases I'm trying to follow a DRY principle, where only the interactions are different with same test case conditions. I'm not able to find a way to implement multiple methods in the interaction { } block.
As mentioned in http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_explicit_interaction_blocks, I'm using interaction { } in the then: block like below:
Java Code:
// legacy code (still running on EJB 1.0 framework, and no dependency injection involved)
// can't alter java code base
public voidGetData() {
DataService ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset() // happy path scenario; missing a null check
// other code
}
// other varieties of same code:
public voidGetData2() {
ItemEJB tmpItem = new ItemEJB();
ItemEJB item = tmpItem.findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
public voidGetData3() {
ItemEJB item = new ItemEJB().findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
Spock Test:
def "test scene1"() {
given: "a task"
// other code ommitted
DataService mockObj = Mock(DataService)
when: "take action"
// code omitted
then: "action response"
interaction {
verifyNoDataScenario() // How to add verifyErrorScenario() interaction to the list?
}
}
private verifyDataScenario() {
1 * mockObj.findByOffset(5) >> mockObj // the findByOffset() returns an object, so mapped to same mock instance
1 * mockObj.getOffset() >> 200
}
private verifyErrorScenario() {
1 * mockObj.findByOffset(5) >> null // the findByOffset() returns null
0 * mockObj.getOffset() >> 200 // this won't be executed, and should ie expected to throw NPE
}
The interaction closure doesn't accept more than one method call. I'm not sure if it's design limitation. I believe more can be done in the closure than just mentioning the method name. I also tried interpolating the mockObj as a variable and use data pipe / data table, but since it's referring the same mock instance, it's not working. I'll post that as a separate question.
I ended up repeating the test case twice just to invoke different interaction methods. Down the line I see more scenarios, and wanted to avoid copy & paste approach. Appreciate any pointers to achieve this.
Update:
Modified shared java code as the earlier DataService name was confusing.
As there's no DI involved, and I didn't find a way to mock method variables, so I mock them using PowerMockito, e.g. PowerMockito.whenNew(DataService.class).withNoArguments().thenReturn(mockObj)
Your application code looks very strange. Is the programming style in your legacy application really that bad? First a DataService object is created with a no-arguments constructor, just to be overwritten in the next step by calling a method on that instance which again returns a DataService object. What kind of programmer creates code like that? Or did you just make up some pseudo code which does not have much in common with your real application? Please explain.
As for your test code, it also does not make sense because you instantiate DataService mockObj as a local variable in your feature method (test method), which means that in your helper method mockObj cannot be accessed. So either you need to pass the object as a parameter to the helper methods or you need to make it a field in your test class.
Last, but not least, your local mock object is never injected into the class under test because, as I said in the first paragraph, the DataService object in getData() is also a local variable. Unless your application code is compeletely fake, there is no way to inject the mock because getData() does not have any method parameter and the DataService object is not a field which could be set via setter method or constructor. Thus, you can create as many mocks as you want, the application will never have any knowledge of them. So your stubbing findByOffset(long offset) (why don't you show the code of that method?) has no effect whatsoever.
Bottom line: Please provide an example reflecting the structure of your real code, both application and test code. The snippets you provide do not make any sense, unfortunately. I am trying to help, but like this I cannot.
Update:
In my comments I mentioned refactoring your legacy code for testability by adding a constructor, setter method or an overloaded getData method with an additional parameter. Here is an example of what I mean:
Dummy helper class:
package de.scrum_master.stackoverflow.q58470315;
public class DataService {
private long offset;
public DataService(long offset) {
this.offset = offset;
}
public DataService() {}
public DataService findByOffset(long offset) {
return new DataService(offset);
}
public long getOffset() {
return offset;
}
#Override
public String toString() {
return "DataService{" +
"offset=" + offset +
'}';
}
}
Subject under test:
Let me add a private DataService member with a setter in order to make the object injectable. I am also adding a check if the ds member has been injected or not. If not, the code will behave like before in production and create a new object by itself.
package de.scrum_master.stackoverflow.q58470315;
public class ToBeTestedWithInteractions {
private DataService ds;
public void setDataService(DataService ds) {
this.ds = ds;
}
// legacy code; can't alter
public void getData() {
if (ds == null)
ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset();
}
}
Spock test:
Now let us test both the normal and the error scenario. Actually I think you should break it down into two smaller feature methods, but as you seem to wish to test everything (IMO too much) in one method, you can also do that via two distinct pairs of when-then blocks. You do not need to explicitly declare any interaction blocks in order to do so.
package de.scrum_master.stackoverflow.q58470315
import spock.lang.Specification
class RepeatedInteractionsTest extends Specification {
def "test scene1"() {
given: "subject under test with injected mock"
ToBeTestedWithInteractions subjectUnderTest = new ToBeTestedWithInteractions()
DataService dataService = Mock()
subjectUnderTest.dataService = dataService
when: "getting data"
subjectUnderTest.getData()
then: "no error, normal return values"
noExceptionThrown()
1 * dataService.findByOffset(5) >> dataService
1 * dataService.getOffset() >> 200
when: "getting data"
subjectUnderTest.getData()
then: "NPE, only first method called"
thrown NullPointerException
1 * dataService.findByOffset(5) >> null
0 * dataService.getOffset()
}
}
Please also note that testing for exceptions thrown or not thrown adds value to the test, the interaction testing just checks internal legacy code behaviour, which has little to no value.

Java CXF: What is the best way to handle Common Objects under different packages or namespaces?

We're integrating with a 3rd Party webservice by using Wsdl2Java to translate their Schema and endpoints into Java for three different webservices that they offer.
This particular provider uses a lot of the same objects (think objects representing an Address, Money, Weight, etc), but, in their infinite wisdom, they've decided to create a different namespace for each webservice and duplicate the definition of their schemas for each one. The result is you have the following classes output for CXF integration:
com.thirdpartyguys.api.firstApi.Money
com.thirdpartyguys.api.secondApi.Money
com.thirdpartyguys.api.thirdApi.Money
Translating our data into theirs can involve a lot of business logic and, as a result, we have to define the code that creates the objects in triplicate for each individual Webservice API.
To overcome this problem I created an Interface defined thusly:
import org.apache.commons.beanutils.BeanUtils;
public interface CommonObjectInterface<A, R, S> {
A toFirstApi();
R toSecondApi();
S toThirdApi();
default Object doTransform(Object destination, Object source) {
try {
BeanUtils.copyProperties(destination, source);
} catch (Exception e) {
throw new RuntimeException("Fatal error transforming Object", e);
}
return destination;
}
}
You would then have each common object implement the interface, define its own constructors, fluent API, etc, and call the toXXX() methods to get the proper form of the object for the respective API.
Right now most of these implementing classes work by keeping a copy of one of the Apis locally, setting data on that, and then transforming it for the proper API using the doTransform() method which in its default form uses the Apache Commons BeanUtils.copyProperties() method.
It's more elegant than having the same code exist in three different places, but not by much! There's a lot of boilerplate and, even though this won't be getting hammered too much, not that efficient.
I would like to get feedback from the community as to whether this is a good idea or if there are better approaches. A similar question was asked years ago here, but I don't know if better solutions have emerged since it was asked. I imagine the best thing would be configuring wsdl2Java to allow setting the namespace at runtime, but from my initial research this does not seem to be possible.
The solution to this problem is specific to this exact situation:
1) A webservice provider that has the same object in different namespaces
2) Using wsdl2Java or some underlying Apache CXF technology to generate the web artifacts for writing a client.
This is a fringe case so I'm not sure how helpful this will be to the community but the trick is to account for a few situations where a copyProperties method doesn't work. In this case I'm using Spring's BeanUtils and BeanWrapper classes although I'm sure this could be adapted for Apache as well. The following code does the trick:
final String TARGET_PACKAGE = "com.thirdpartyguys.api";
public Object doTransform(Object destination, Object source) {
/*
* This will copy all properties for the same data type for which there is a getter method in
* source, and a setter method in destination
*/
BeanUtils.copyProperties(source, destination);
BeanWrapper sourceWrapper = new BeanWrapperImpl(source);
for(PropertyDescriptor p : sourceWrapper.getPropertyDescriptors()) {
/*
* Properties that are references to other schema objects are identical in structure, but have
* different packages. We need to copy these separately
*/
if(p.getPropertyType().getPackage().getName().startsWith(TARGET_PACKAGE)) {
try {
commonPropertyCopy(destination, source, p);
} catch (Exception e) {
throw new RuntimeException("Fatal error creating Data", e);
}
}
/*
* Properties that reference list don't create setters according to the Apache CXF
* convention. We have to call the get method and addAll()
*/
else if(Collection.class.isAssignableFrom(p.getPropertyType())) {
try {
collectionCopy(destination, source, p);
} catch (Exception e) {
throw new RuntimeException("Fatal error creating Data", e);
}
}
}
return destination;
}
private void collectionCopy(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
BeanWrapper destWrapper= new BeanWrapperImpl(destination);
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(sourceProperty.getName());
Collection<?> sourceCollection = (Collection<?>) sourceProperty.getReadMethod().invoke(source);
Collection<Object> destCollection = (Collection<Object>) destProperty.getReadMethod().invoke(destination);
destCollection.addAll(sourceCollection);
}
private void commonPropertyCopy(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
if(sourceProperty.getPropertyType().isEnum()) {
instantiateEnum(destination, source, sourceProperty);
}
else {
instantiateObject(destination, source, sourceProperty);
}
}
private void instantiateEnum(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
BeanWrapper destWrapper= new BeanWrapperImpl(destination);
Enum<?> sourceEnum = (Enum<?>) sourceProperty.getReadMethod().invoke(source);
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(sourceProperty.getName());
Object enumValue = Enum.valueOf(destProperty.getPropertyType().asSubclass(Enum.class), sourceEnum.name());
destProperty.getWriteMethod().invoke(destination, enumValue);
}
private void instantiateObject(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
Object subObj = sourceProperty.getReadMethod().invoke(source);
if(subObj!=null) {
BeanWrapper destWrapper = new BeanWrapperImpl(destination);
String subObjName = sourceProperty.getName();
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(subObjName);
Class<?> propertyType = destProperty.getReadMethod().getReturnType();
Object subObjCopy = propertyType.getConstructor().newInstance();
doTransform(subObjCopy, subObj);
destProperty.getWriteMethod().invoke(destination, subObjCopy);
}
}
instantiateObject is used to create new instances of the "identical" objects from different packages. This also applies for Enumerated types and requires its own method, hence the implementation of instantiateEnum. Finally, the default CXF implemenation offers no setter method for Lists. We handle this situation in collectionCopy.

Service which provides interface-impelementation instead of data

Since a while now I'm implementing services whenever possible with ServiceStack (or WebAPI) instead of WCF.
What I want to do now is sending an interface (-name) to the server and get a class-implementation back. Maybe that's confusing, so I'll give you an example:
My service-client has multiple operations - like "check form":
The logic for checking this form is not implemented. What it has is an interface called IFormChecker with methods like NameIsValid(string firstName, string middleName, string lastName).
Instead of sending the whole form-data to the server for validation, the client will request the implementation of IFormChecker from the server.
I know that's possible with WCF, but I have no idea how to do that with ServiceStack.
If that's possible, what's the way to go? I checked the documentation, but I'm not really wiser.
It seams like there's no "magic trick" or anything.
I have to serialize/deserialize the class "old-fashion way".
If you're interested, here's the solution:
I created a "Root"-Interface, in this example it is IModule.
This IModule contains only 1 property, called Name.
It is a string and only there for convenience:
The IFormChecker from the example would be derived from this interface:
My client knows the value of this Name-property and of course the interface itself.
It will now fire the Name-value to the server, which will return the serialized class.
All I have to do is:
var module = ModuleImplementations.FirstOrDefault(x => x.Name == name);
if(module == null) throw new SomeException();
return module.Serialize();
client-wise I can deserialize it and cast it to the interface. That's it.
Here's my ModuleSerialization-Class:
public static class ModuleSerialization
{
public static string Serialize(this IModule m)
{
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, m);
return Convert.ToBase64String(ms.ToArray());
}
}
public static T Deserialize<T>(string serialized) where T : class, IModule
{
var ba = Convert.FromBase64String(serialized);
using (var s = new MemoryStream(ba))
{
var bf = new BinaryFormatter();
return bf.Deserialize(s) as T;
}
}
}
Cheers!

Trying to create a List of user-defined objects, getting NullPointerException

I'm working on an Android app. I created (in a separate .java file) an object like so:
class RRS_Location {
String tagname;
String href;
// Constructor
public RRS_Location(String tagname, String href) {
this.tagname = tagname;
this.href = href;
}
public String getTagname() {
return tagname;
}
public String getHref() {
return href;
}
}
Within an activity, I've declared a List of these items
List<RRS_Location> rrs_list;
I'm getting a NullPointerException when I try to add an RRS_Location object to the list. I'm doing so using this code
rrs_list.add(new RRS_Location(e1, e2));
I've used Toast to echo back to me that I have valid Strings e1 and e2. Any ideas on why I'm getting the exception? TIA!
Are you instantiating rrs_list before making the call to add?
List<RRS_Location> rrs_list = new ArrayList<RRS_Location>();
If not, this is why you are getting a NullPointerException, you are attempting to invoke a method on a null object.

Code Design / Testability How To?

My team is designing a library that is wrapping calls to Active Directory to search and return a list of people.
We have a person class that wraps up the information for a person found. We then use the List to wrap them up. When we call the search it uses the internal System.Directory library and returns a SearchResultCollection object. We then iterate through it to build up the list<> and return that.
We have designed the person class to only have read only (get) properties since we don't want the callee to change the person info. We pass in the SearchResult object from the System.Directory library on the constructor of the person.
My issue is we can't test this easily.
My thoughts so far have been:
Pass variables into the person constructor for each property needing to be set.
Unfortunately, this will make for a very long constructor parameter list.... Smells bad to me.
Allow the person class to have setters on the properties.
Again, smells bad to me since we can't control the callee from using this.
Refactor:
I have looked at the extract to interface and adapt parameter techniques. It seems the adapt parameter has the most promise? Adapt parameter seems nice because it does help break the dependency I have on the Directory Library's SearchResult object. So if in the future I wanted to do some other kind of search we are in good shape. At least I think we are?
Sub class the person object and create a test Person with setters....
Seems like it would work but not sure if it's the right way to go?
Mock it
Haven't done any mocking yet so again not sure on this one.
EDIT: If mocking is best idea please let me know... However, I would be interested to know how this would be done without mocking also (or perhaps it really isn't do able without mocking)....
I would appreciate guidance on this one.
Here's a snippet of the code:
public class PeopleSearcher
{
.... declarations left out....
public List<Person> FindPerson(string FirstName, string LastName, string Login)
{
...filter setup left out for brevity....
_peopleFound = _directoryToSearch.FindAll();
//Convert to list of persons....
int cnt = 0;
_listOfPeople = new List<Person>();
while (cnt < _peopleFound.Count)
{
Person p = new Person(_peopleFound[0]);
_listOfPeople.Add(p);
cnt++;
}
return _listOfPeople;
}
}
public class Person
{
private string sn;
....further declarations left out for brevity....
public Person(SearchResult PersonFound)
{
sn = PersonFound.Properties["sn"].Count == 0 ? string.Empty : PersonFound.Properties["sn"][0].ToString();
givenName = PersonFound.Properties["givenName"].Count == 0 ? string.Empty : PersonFound.Properties["givenName"][0].ToString();
sAMAccountName = PersonFound.Properties["sAMAccountName"].Count == 0 ? string.Empty : PersonFound.Properties["sAMAccountName"][0].ToString();
adsPath = PersonFound.Path == null ? string.Empty : PersonFound.Path;
}
public string LastName
{
get
{
return sn;
}
}
.... more getters...
}
}
"Mocking" is a word that is usually used for all kinds of test doubles. And most times people or not "mocking", they're faking or stubbing. Anyway, your 4th option (subclass and add setters) sounds to me like the easiest way to go given your codebase assuming you want Person objects to pass toother methods. Because I don't think you're talking about testing that the person object gets the properties set correct by the constructor, right?
Mock it. This is the sort of situation that mocking was invented for. I've only done mocking in Ruby, so I'm not sure of the state of the art for .net, but it should work well.
When mocking it you might realize some areas that should be refactored. This is also a good plan.
In your mock (by framework or otherwise), you're still going to end up having to create Person objects with values, which leads you right back to your original problem.
Fortunately, there are two excellent solutions:
1) Go ahead and add setters to the Person class, but make them protected. This means your mock and test code would have to be in the same package, but would block other users from mutating your Persons. (and we don't want mutants running around - there's been enough of that in the movies lately).
2) Use a Builder class (as Joshua Bloch describes in Effective Java). You'd create a public static PersonBuilder class inside Person, which would export a build method and chainable parameter specifiers (like setters, but not separately callable):
public class Person ....
public static class PersonBuilder {
public PersonBuilder (String firstName, String lastName) {...} // my sample has two required values
public Person build() { ... }
public PersonBuilder ssn (String value) { ... }
public PersonBuilder adsPath (String value) { ... }
...
}
...
}
The chainable value specifiers look like this:
public PersonBuilder ssn (String value) {
this.sn = value;
return this;
}
Then a call to create a Person looks like this:
Person thisPerson = new Person.PersonBuilder ("John", "Smith").ssn("123-45-6789").adsPath("whatever");
This method completely hides the methods which can set the values (indeed, you have no "setters"), but keeps you from having to deal with long constructor argument lists (which makes it easier to deal with optional values).
Incidentally, you also probably want to make Person's constructor private.