I'm using realm as database and kotlin as language.
I implemented my custom setter method for a property.
Does Realm call this setter somehow?
For example:
open class Human(): RealmObject()
{
open var Name: String = ""
set(value)
{
setName(value)
}
}
Now I also have a property changeDate and it would be nice if I can set the changeDate automatically in the setNameto new actual day.
But I can't do this if Realm calls this method also.
Thanks
I've tried this with Kotlin 1.1.1 and Realm 3.0.0, and it doesn't call the custom setter, it assigns the value in some other way (which means that it even works if your custom setter is empty, which is a bit unexpected).
Edit: Looked at the generated code and the debugger.
When you're using an object that's connected to Realm, it's an instance of a proxy class that's a subclass of the class that you're using in your code. When you're reading properties of this instance, the call to the getter goes down to native calls to access the stored value that's on disk, inside Realm.
Similarly, calling the setter eventually gets to native calls to set the appropriate values. This explains why the setter doesn't get called: Realm doesn't need to call the setter, because it doesn't load the values into memory eagerly, the proxy is just pointing into the real data in Realm, and whenever you read that value, it will read it from there.
As for how this relates to Kotlin code, the calls to the proxy's setter and getter that access the data inside Realm happen whenever you use the field keyword (for the most part).
var Name: String = ""
get() {
return field // this calls `String realmGet$Name()` on the proxy
}
set(value) {
field = value // this calls `void realmSet$Name(String value)` on the proxy
}
Related
I am building an WPF application using the MVVM Light Toolkit and specifically SimpleIoc.
I have a parent viewmodel that dynamically creates child viewmodels. When doing this I am using "standard" dependency injection to pass a IConfigService as a parameter to the constructor. I want the IConfigService to be a unique instance for each child viewmodel. So I try this:
IConfigService service = SimpleIoc.Default.GetInstance<IConfigService>(key);
ChildViewModel vm = new ChildViewModel(service);
Where key is a unique identifier for each child viewmodel. According to the documentation of MVVM Light and SimpleIoc this GetInstance method:
...provides a way to get an instance of a given type corresponding to a given key. If no instance had been instantiated with this key before, a new instance will be created.
There is also a remark that the class must have been registered before, else it returns null. In my case it has been, in ViewModelLocator:
var configService = new ConfigService();
SimpleIoc.Default.Register<IConfigService>(() => configService);
However, the GetInstance call returns the same instance every time.
What am I doing wrong here?
You registered an already instantiated object.
SimpleIoc does not create its own instances with this overload. It always returns configService. Either you need to perform the instantiation within the lambda, because you are using a factory overload, or you can do this more easily by just passing the ConfigService type. SimpleIoc will take care of the instantiation itself.
I ran into the following SpringMVC issue: there is a domain object which uses a certain Address sub-object, but the getters/setters have to be tweaked to use a different Address object via conversion. This is an architectural requirement.
public class DomainObj {
protected DomainObj.Address address;
public anotherpackage.new.Address getAddress()
{
return convertFrom(address);
}
public void setAddress (anotherpackage.new.Address value)
{
this.address = convertTo(value);
}
}
// Internal Address object, old, #1
public static class Address {
protected String street1;
protected String street2;
// etc., getters/setters
}
Now, in the JSP, I bind an Input Text Field to the new Address object (the result of conversions) that's what we have to deal with. In this new 2nd Address object (anotherpackage.new.Address), there is a field e.g. "addressLine1", which is different from the old object's "Street1":
<form:input path="topObject.address.addressLine1" />
My problem is that the setter, setAddress(), never gets called in this case for binding (verified in the Debugger). Any solutions to this?
Your options are:
a) do not bind directly to the business object
b) configure a binder to do the conversion to your domain object
Discussion:
Usually in enterprise class software we don't want to bind directly to the business objects -- which are usually entities (in the context of jpa). This is because session handling is a bee-otch. Usually we code against DTOs, and when one is received from the front-end we read the appropriate object from the repository (ORM) layer, update it, and save it back again (I've only described updates because they're the hardest, but a similar model works for everything).
However, spring mvc binders offer a way of binding anything to anything. They're a bit complicated and it'll take too long to explain here, but the docs are in the spring documentation and you want to be looing at converters and a conversion service. There are SO Q/A's on this topic, for example...
For example, let's say I have an interface 'IFeed' and two concrete types ('Feed1' and 'Feed2') that implement this interface. Now let's say I have a 'FeedManager' type that takes multiple parameters that will get resolved dynamically, two of which are of type 'IFeed' and I'd like both concrete type to be injected via constructor injection, not via manual resolve (I only use resolve once at the composition root). I have a feeling that I should be using a factory but I wanted to see what the proper way of doing this might be. Many thanks in advance.
If you want ALL implementations of IFeed, you can use array syntax in your constructor and then nothing special is needed at type registration time.
container.RegisterType<IFeedManager, FeedManager>();
container.RegisterType<IFeed, FeedA>("FeedA"); // The name doesn't matter
container.RegisterType<IFeed, FeedB>("FeedB"); // The name doesn't matter
Then the manager constructor...
public FeedManager(IFeed[] feeds) {...}
or if you want to add a little flare for calling the constructor directly...
public FeedManager(params IFeed[] feeds) {...}
Assuming you want to determine the actual concrete instances at runtime, you need to use named type registrations and then tell unity which one you want. So, use a factory method to construct the types required and pass those in as parameter overrides. Unity will use the overrides and resolve any remaining dependencies.
// register the types using named registrations
container.RegisterType<IFeedManager,FeedManager>()
container.RegisterType<IFeed, Feed1>("Feed1")
container.RegisterType<IFeed, Feed2>("Feed2")
Assuming your feed manager has the following named constructor parameters
class FeedManager : IFeedManager
{
public FeedManager (IFeed Feed1, IFeed Feed2, string someOtherDependency)
{
}
}
and create your feed manager:
static IFeedManager CreateFeedManager()
{
ParameterOverride feed1 = new ParameterOverride("Feed1"
,_container.Resolve<IFeed>("feed1"));
ParameterOverride feed2 = new DependencyOverride("Feed2"
,_container.Resolve<IFeed>("feed2"));
IFeedManager = _container.Resolve<IFeedManager>(feed1,feed2)
return IFeedManager;
}
Obviously this is overly simplified, but you you insert your own logic to determine which instance is to be resolved and then injected for each of the IFeed instances required by the FeedManager.
With Unity you would do this like so:
container.RegisterType<IFeed, Feed1>("Feed1");
container.RegisterType<IFeed, Feed2>("Feed2");
container.RegisterType<FeedManager>(new InjectionConstructor(new ResolvedParameter<IFeed>("Feed1"),
new ResolvedParameter<IFeed>("Feed2")));
This has now configured Unity so that when it needs to resolve a FeedManager, it will resolve Feed1 for the first parameter and Feed2 for the second parameter.
I have been adapting our code in preparation of moving our code to the new 2.1 Symfony codebase.
In 2.0.* we could set Flash messages by simply calling the session service in our controller using the following
$this->get('session')->setFlash('type', 'message');
I have trawled through the new documentation, I was just wondering if there was a clean way, similar to the above; rather than just calling the FlashBagInterface?
Try:
$this->get('session')->getFlashBag()->set('type', 'message');
Also, you might want to try the add() method instead, which won't obliterate other flash messages:
$this->get('session')->getFlashBag()->add('type', 'message');
FYI:
The Symfony HttpFoundation component has a very powerful and flexible session subsystem which is designed to provide session management through a simple object-oriented interface using a variety of session storage drivers.
FlashBagInterface has a simple API:
set(): Sets an attribute by key;
get(): Gets an attribute by key;
all(): Gets all attributes as an array of key => value;
has(): Returns true if the attribute exists;
replace(): Sets multiple attributes at once: takes a keyed array and sets each key => value pair;
remove(): Deletes an attribute by key;
clear(): Clear all attributes.
Source: Symfony2: Session Management
I'm trying to query UserMetaData for a single record using the following query
using (JonTestDataEntities context = new JonTestDataEntities())
{
return context.UserMetaData.Single(user => user.User.ID == id);
}
The error I'm receiving is: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. It is trying to lazyload Group for UserMetaData record. How can I change my query to prevent this error?
As the message says, you cannot lazily load it after the function returns, because you've already disposed the context. If you want to be able to access Group, you can make sure you fetch it earlier. The extension method .Include(entity => entity.NavigationProperty) is how you can express this:
using (JonTestDataEntities context = new JonTestDataEntities())
{
return context.UserMetaData.Include(user => user.Group).Single(user => user.User.ID == id);
}
Also consider adding .AsNoTracking(), since your context will be gone anyway.
You need to create a strong type that matches the signature of your result set. Entity Framework is creating an anonymous type and the anonymous type is disposed after the using statement goes out of scope.
So assigning to a strong type avoids the issue altogether. I'd recommend creating a class called UserDTO since you're really creating a data transfer object in this case. The benefit of the dedicated DTO is you can include only the necessary properties to keep your response as lightweight as possible.