RepositoryEventHandler HandleAfterLinkDelete access to unlinked object - spring

I couldn't find any documentation but I wonder if it is possible to access the unlinked object in the link event handler? Upon debugging, it is a proxy object but why pass it as parameter if it's not accessible.
#HandleAfterLinkDelete
public void handleAfterUnlinked(Entity entity, Object unlinked) {
//unlinked is a proxy object
}
or even in the before handler
#HandleBeforeLinkDelete
public void handleBeforeUnlinked(Entity entity, Object unlinked) {
//unlinked is a proxy object
}

The 2nd parameter will be a Proxy instance whose underlying object will be an instance of Collection of the type of the associated field. The unlinked (in case of the Delete events) or the linked object (in the case of the Save events) can be accessed by casting the second parameter to a collection and getting its content.
If the Entity class as a collection property of type X, you could use:
#HandleAfterLinkDelete
public void handleAfterUnlinked(Entity entity, Object unlinked) {
if (unlinked instanceof Collection) {
Collection unlinkedCollection = (Collection) unlinked;
// use the collection
}
}
Note that there is not reference to the specific object that was unlinked (or the object that is linked, for the LinkSaved events). That appears like a bug in the Spring Data implementation.

Related

Laravel — How to get string value from object via model method?

I have model House with relation hasMany HousePhotos.
I try get link to main photo from table house_photos.
class House extends Model
{
public function photos(){
return $this->hasMany('app\HousePhoto');
}
public function get_main_photo(){
return $this->photos()->where('main', true);
}
}
Controller:
$house=House::find(1);
In View i use
{{$house->main_photo()->link}}
and got error.
When i use
{{$house->main_photo()}}
i got object. How to get string value of link to photo?
First of all you need to understand the difference between the Builder object and the Collection object.
As it is now, function get_main_photo returns a Builder object (actually a Relation object, which contains a Builder).
On these objects you can call function get() to finish the query and get the results. In this case you will get a Collection object, which you will be able to iterate.
Alternatively, in this case you seem to only have one 'main photo' per house, so instead you can call first():
public function get_main_photo(){
return $this->photos()->where('main', true)->first();
}
This will return the single associated model, on which you will be able to access ->link (if the model was found).
Remember at any point while debugging you can call the convenient dd function (which dumps the object passed as parameter and terminates the applicacion) to see what type of object you are dealing with, and all its attributes.

Regarding Events in Openbravo onSave need to get an client and set it into other class object

Here My code
Need to populate it from a class and then set in to another class especially all columns in product to product detail (Some How i managed other but My Problem is regarding Client. It is not showing anything)
public void onSave(#Observes EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity product_Shift =ModelProvider.getInstance().getEntity(OCAProducts.ENTITY_NAME);
ProductsDetails pd = OBProvider.getInstance().get(ProductsDetails.class);
final Property pro_client = product_Shift.getProperty(OCAProducts.PROPERTY_CLIENT);
pd.setClient((Client) event.getCurrentState(pro_client));
OBDal.getInstance().save(pd);
OBDal.getInstance().flush();
Getter and setter methods do not work in Openbravo event handlers. Check the document from Openbravo's wiki here.
An excerpt from the wiki page.
don't call setters on the Greeting instance itself, this does not work
because when the event has been broadcasted, Hibernate has already
read the state of the object. So you must change the value through the
special setCurrentState method
Example
event.setCurrentState(clientProperty, clientId);
event.setCurrentState(pro_client, clientID)

Autofac - Inject ModelState into Service

I want to be able to inject model state into a service.
Service
public ThirdPartyService(IValidationDictionary dict)
{
// IValidationDictionary, in this case is a ModelStateWrapper object
// I created to wrap model state
}
Registration
builder.Register(x => new ModelStateWrapper(x.Resolve<ControllerType>().ViewData.ModelState))
.As<IValidationDictionary>().InstancePerHttpRequest();
Any ideas?
This doesn't make sense as an InstancePerHttpRequest.
There can be a lot of controllers and there can be a lot of model states during a single Http request. Even if you access the current ControllerContext object through a refference in say, HttpContext.Current , the code you will produce is prone to bugs and malfunction due to design.
What I would suggest is to create an in-memory service-like repository to store all current ModelState and retrieve them by a controller-action key like (plain stupid example):
interface IHttpRequestModelStates
{
ICollection<string, ModelState> ModelStates {get; set;}
// you can retrieve Controller:Home / Index model state
// using ModelStates["HomeIndex"]
}

Not tracking a single property of an entity with EF4

My MVC action method receives an entity object (Page) that the default model binder creates from form collection data. Some of the fields are wrong or null because they were not sent in the request to the server, for example I do not send "CreateDate" and the default model binder sets this property to some default value which I don't need.
Once the object is attached it of course tries to persist all the values (including invalid/not needed ones to the database). I could of course assign manually on a per property basis but was wondering if maybe I can somehow flag a property so it is not persisted when EntityState is set to modified and SaveChanges() is called..
public ActionResult SomeMethod(Page page)
{
page.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(page);
_db.ObjectStateManager.ChangeObjectState(page, System.Data.EntityState.Modified);
_db.SaveChanges();
_db.Dispose();
}
The correct way to handle this is using different class for view model, attach empty entity to the context and assign real values per property (or let AutoMapper to handle this scenario) as #Darin suggested in the comment.
If you want to go your way you must not change state of the POCO entity but you must change state of every changed property:
public ActionResult SomeMethod(Page page)
{
page.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(page);
ObjectStateEntry entry = _db.ObjectStateManager.GetObjectStateEntry(page);
entry.SetModifiedProperty("ChangedPropertyName");
// Do the same for all other changed properties
_db.SaveChanges();
_db.Dispose();
}

In Spring MVC 3, how do I bind an object to a query string when the query string parameters don't match up with the object fields?

A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?

Resources