Im working on a mvc 2.0 application using the entity framework. With the entityframework I use the repository pattern with poco objects. To start off with the issue, when I convert an entity object to json I get a circular reference error.
After some search I discovered that there are proxy's generated to support lazy loading. If there are navigation properties between two classes (A and B), this results in a circurar reference error. Quite understandable. So I try to work around it.
I disabled the proxies and the lazy loading. This works if I only want to load Class A. Instead of the proxy's there are now null values, so they can be parsed.
But now I want to load a class, for instance Orders and I want to see what customer placed the order:
Suppose I have class Customer that has a navigation property to Order (1 to more) and Order has a reversed navigation property to Customer. When I turn the proxys off, I get a nice json back with all the orders, but not with the Customers. When I turn the proxies on, I get a circular error.
But how could I get back the orders, with the customer that bought them. Is it possible to create a linq that retreives the orders and load the customers (I have a repository for both customers and orders)? Or is there a way to strip off the proxy-objects?
I hope my post is clear enoug and someone can help me.
Problem:
Right. So you have the relationship A -> B with B being the many side.
in the EF model A gets a navigation property B and B gets a navigation property A.
Circular reference... great...
Solution:
In your model, rightclick on the B's navigation property A and choose properties.
Getter and setter there should both be public initially. Set the getter to Private.
Now something like this should work.
var results = from a in ctx.A.Include("B")
select a;
var list = results.ToList(); //This is important otherwise youll get a error that the context has been disposed on the next line.
return Json(list, JsonRequestBehavior.AllowGet);
Hope this helps.
PS:
After reading my answer after posting it, I'm not so sure anymore that I'm really answering your question, sorry. Ill leave it up nonetheless.
Related
I'm currently building a HATEOAS/HAL based REST application with Spring MVC and JPA (Hibernate). Basically the application gives access to a database and allows data retrieval/creation/manipulation.
So far I've already got a lot of things done including a working controller for one of the resources, let's call it x.
But I don't want to give the API user the opportunity to create just an x resource, because this alone would be useless and could be deleted right away. He/she also has to define a new y and a z resource to make things work. So: Allowing to create all those resources independently would not break anything but maybe produce dead data like a z resource floating around without any connection, completely invisible und useless to the user.
Example: I don't want the user to create a new customer without directly attaching a business contract to the customer. (Two different resources: /customers and /contracts).
I did not really find any answers or best practice on the web, except for some sort of bulk POSTing, but only to one resource, where you would POST a ton of customers at once.
Now the following options come to my mind:
Let the user create the resources as he/she wants. If there are customers created and never connected to a contract - I don't care. The logic here would be: Allow the user to create /customers (and return some sort of id, of course). Then if he/she wants to POST a new /contract later I would check if the customer's id given exists and if it does: create the contract.
Expect the user, when POSTing to /customers, to also include contract data.
Option 1 would be the easiest way (and maybe more true to REST?).
Option 2 is a bit more complicated, since the user does not send single resources any more.
Currently, the controller method for adding a customer starts like that:
#RequestMapping(value = "", method = RequestMethod.POST)
public HttpEntity<Customers> addCustomer(#RequestBody Customers customer) {
//stuff...
}
This way the JSON in the RequestBody would directly fit in my customers class and I can continue working with it. Now with two (or more) expected resources included in the RequestBody this cannot be done the same way any more. Any ideas on how to handle that in a nice way?
I could create some sort of wrapper class (like CustomersContracts), that consists of customers and contract data and has the sole purpose of storing this kind of data in it. But this seems ugly.
I could also take the raw JSON in the RequestBody, parse it and then manually create a customer and a contract object from it, save the customer, get its id and attach it to the contract.
Any thoughts?
Coming back to here after a couple of months. I finally decided to create some kind of wrapper resource (these are example class names):
public class DataImport extends ResourceSupport implements Serializable {
/* The classes referenced here are #Entitys */
private Import1 import1;
private Import2 import2;
private List<Import3> import3;
private List<Import4> import4;
}
So the API user always has to send an Import1 and Import2 JSON object and an Import3 and Import4 JSON array (can also be empty).
In my controller class I do the following:
#RequestMapping(*snip*)
public ResponseEntity<?> add(#RequestBody DataImport dataImport) {
Import1 import1 = dataImport.getImport1();
Import2 import2 = dataImport.getImport2();
List<Import3> import3 = dataImport.getImport3();
List<Import4> import4 = dataImport.getImport4();
// continue...
}
I still don't know if it's the best way to do this, but it qorks quite well.
I Have Create a DB in that I am Having Multiple tables having Relationship between them.
When a try to get data from my WEb app i get this error
"'Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.PrescriptionMaster_2C4C63F6E22DFF8E29DCAC8D06EBAE038831B58747056064834E80E41B5C4E4A'. Path '[0].Patient.PrescriptionMasters"
I coudn't get why i am getting this error, and when i remove the relationships between tables i get proper data From it.
I have Tried other solutions like adding
"config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore; "
in Webconfig.cs but nothing has worked for me.
Please help me, what should I do ?
The only proper way to prevent this from happening is by not sending Entity Framework objects (which may contain such loops) into the JSON Serializer (which is not too good at knowing when to stop serializing).
Instead, create ViewModels that mimic the parts of the EF Objects that your Front End actually needs, then fill those ViewModels using the EF Objects.
A quick-and-dirty way is to just use anonymous objects, for example:
return new
{
Product = new
{
Id = EF_Product.Id,
Name = EF_Product.Name
}
};
A good rule-of-thumb is to only assign simple properties (number, bool, string, datetime) from the EF Objects to the ViewModel items. As soon as you encounter an EF Object property that is yet another EF Object (or a collection of EF Objects), then you need to translate those as well to 'simple' objects that are not linked to EF.
On the other end of the spectrum there are libraries such as AutoMapper. If you decide that you need actual ViewModel classes, then AutoMapper will help mapping the EF Objects to those ViewModels in a very structured way.
Just add this to the Application_Start in Global.asax:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter
.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
It will ignore the reference pointing back to the object.
I want to know if I can have a single createCriteria() call, that returns me the whole table, and some specified joined columns.
Something like this:
SELECT table1.*, table2.property1,table2.property2 FROM table1 WHERE ... INNER JOIN table2.
I have a code similar to this:
MyDomainClass.createCriteria().list{
createAlias("relationedObject", "relationedObjectAlias")
condition1(...)
condition2(...)
condition3(...)
projections{
property("relationedObjectAlias.nestedProperty")
property("someProperty")
property("anotherProperty")
}
}
It returns me an array of arrays, containing these 3 properties listed inside the projections closure. But what should I do to receive the whole MyDomainClass object row, AND the projections?
What I really need, actually, is an array containing the whole MyDomainClass object, and the nestedProperty from the relationedObject.
I know I could just do another createCriteria() call, without specifying the projections, and manually "join" them in code, but this looks ugly to me... any ideas?
I'm using grails 2.5.5
I don't think there is a way in Hibernate to accomplish what you are doing so (nothing in the documentation that I've seen) and since you are using a HibernateCriteriaBuilder, I would say no.
I think your alternative would be to have all of your domain class's properties defined within your projection, depending on how many properties are involved you could do this manually or with some help:
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
import org.hibernate.criterion.CriteriaSpecification
...
def propertyNames = new DefaultGrailsDomainClass(MyDomainClass.class).
getPersistentProperties().
findAll{ p -> !p.isOneToMany() }*.
name
MyDomainClass.createCriteria().list{
createAlias("relationedObject", "relationedObjectAlias")
condition1(...)
condition2(...)
condition3(...)
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
projections{
property("relationedObjectAlias.nestedProperty")
propertyNames.each{ pn ->
property(pn, pn)
}
}
}
I would not call it pretty but it may work for your situation; I tested it on several of my domain objects and it worked successfully. I'm using DefaultGrailsDomainClass because getPersistentProperties() is a method on a non-static method and I don't want to rely on any particular instance. I'm excluding any collections based on my own testing.
Rather than relying on an returned array and the position of properties within that array, I'm using the ALIAS_TO_ENTITY_MAP result transformer to return a map. I think this is generally a good idea anyways, especially when dealing with larger result sets; and I think it's absolutely critical if gathering the properties in an automated fashion. This does require the property(<String>, <String>) method call as opposed to just the `property()', with the 2nd argument being the map key.
Just started coding with Appwarps and I'm running into an issue. I have a lobby built that shows live rooms, but I really do not want to show the rooms for matches that have already started. I figured I would use
void Client::setCustomRoomData(std::string roomId, std::string customData)
But I have some doubts on how to use it. Once the game starts, I plan on sending
SetCustomRoomData(roomId, "Closed");
to notify the server that open seating is now closed. However, when I check the room properties on another device when it calls
void CCAppwarpDelegate::onGetLiveRoomInfoDone(AppWarp::liveroom revent)
{
CCLog("CustomData=%s",revent.customData.c_str());
...
it returns blank. What am I missing here? Besides the code not working, what really makes me question myself is that I don't understand the mechanics of the properties. How do you have multiple custom properties since you aren't assigning it any kind of index...or do room only have a single custom property at any given time?
You don't need to use customData and instead use only room properties. Room properties is a set of key/value pairs that you can associate with a room.
I recommend you read the following link
http://appwarp.shephertz.com/game-development-center/matchmaking-basic-concept/
So the flow is as follows -
you first create the room using the createRoom API and pass a
properties dictionary containing <"closed", "false">.
Then once the game is active, you use updateRoomProperties API
on the room and pass <"closed", "true"> to the API.
Then when you want to show the list you should use
getRoomWithProperties and pass <"closed", "false">. This will get
you a list of rooms that are not yet "closed".
I'm writing a program to do a search and export the output.
I have three primary objects:
Request
SearchResults
ExportOutput
Each of these objects links to its precursor.
Ie: ExportOutput -> SearchResults -> Request
Is this ok? Should they somehow be more loosely coupled?
Clarification:
Processes later on do use properties and methods on the precursor objects.
Ie:
SendEmail(output.SearchResults.Request.UserEmail, BODY, SUBJECT);
This has a smell even to me. The only way I can think to fix it is have hiding properties in each one, that way I'm only accessing one level
MailAddress UserEmail
{
get { return SearchResults.UserEmail; }
}
which would yeild
SendEmail(output.UserEmail, BODY, SUBJECT);
But again, that's just hiding the problem.
I could copy everything out of the precursor objects into their successors, but that would make ExportOutput really ugly. Is their a better way to factor these objects.
Note: SearchResults implements IDisposable because it links to unmanaged resources (temp files), so I really don't want to just duplicate that in ExportOutput.
If A uses B directly, you cannot:
Reuse A without also reusing B
Test A in isolation from B
Change B without risking breaking A
If instead you designed/programmed to interfaces, you could:
Reuse A without also reusing B - you just need to provide something that implements the same interface as B
Test A in isolation from B - you just need to substitute a Mock Object.
Change B without risking breaking A - because A depends on an interface - not on B
So, at a minimum, I recommend extracting interfaces. Also, this might be a good read for you: the Dependency Inversion Principle (PDF file).
Without knowing your specifics, I would think that results in whatever form would simply be returned from a Request's method (might be more than one such method from a configured Request, like find_first_instance vs. find_all_instances). Then, an Exporter's output method(s) would take results as input. So, I am not envisioning the need to link the objects at all.