Persistent object:
#Entity
public class PersistentModelObject{
...
}
I need something like:
interface GenericDao<T annotated_with Entity>{
//crud
}
Or can it be simulated in some way (with extension, implementation, etc).
EDIT: Please someone who understands my question to edit it to some understandable level.
I dont think you can use annotations like that via generics, but you can use java.lang.Class java.lang.reflect.Field isAnnotationPresent(YourAnnotation.class) to check if a class is annotated with a certain annotation.
A better aproach might be using marker interfaces? Something like:
public class PersistentModelObject implements MyPersistableType{
...
}
and
interface MyPersistableType {} //marker interface
Then you may use it like this:
interface GenericDao<T extends MyPersistableType>{
//crud
}
But then again, it depends on what you are trying to solve.
This restriction can only be checked at runtime using reflection.
Related
If I want to read some JSON into an object, and I have the interface but must use the Spring context to get the implementation class, I need to use a SimpleAbstractTypeResolver to map the interface to the implementation. So far, so good, if I know in advance what interfaces go to what implementation. But if the interface has methods that return other interfaces--and possibly down the line recursively--and I don't necessarily know in advance, I thought I could use reflection to figure it out. So this is what I came up with, but the compiler does NOT like the line resolver.addMapping(method.getReturnType(), method.getReturnType());, says it's not applicable for these arguments. I'm pretty sure the types are okay for that method--any thoughts on how to make this happen?
for (Method method : clazz.getMethods()) {
if (method.getReturnType().isInterface() && method.getName().startsWith("get")) {
// getter method returns an interface so find its implementation class
Class beanClass = context.getBean(method.getReturnType()).getClass();
if (clazz.isAssignableFrom(beanClass)) {
resolver.addMapping(method.getReturnType(), method.getReturnType());
mapInterfaces(objectMapper, clazz, resolver);
}
}
}
Probably you need to review your types.
My guess is following:
resolver.addMapping(method.getReturnType(), beanClass);
(replace second parameter method.getReturnType() with beanClass)
or as an alternative (the code is not completely clear for me, sorry)
resolver.addMapping(clazz, beanClass);
You should put an Interface and Implementation into addMapping().
Example:
interface ITest{};
class TestImpl implements ITest {}
usage:
resolver.addMapping(ITest.class, TestImpl.class);
Probably you need to review your types.
My guess is following:
new ObjectMapper().writerFor(<Interface>.class).writeValuesAsArray(<Class>);
I'm looking to create an interface for my plugin which uses a different class depending on the servers version.
I've tried to include the following in my interface class:
Map<String, EntityPlayer> getPlayers();
However 'EntityPlayer' is imported depending on version, and so it's not viable for me to do this. I essentially need it to be a 'wildcard', where it can be any EntityPlayer import. Then in classes where my interface is implemented, I can use the per-version import.
Hopefully this clarifies what I'm trying to accomplish and what I have done so far.
Thanks all.
You can use a generic Interface something like this
interface YourInterface<T> {
Map<String, T> getPlayers();
}
you could also use a more specific constraint if EntityPlayer is derived from a parent class e.g
interface YourInterface<T extends EntityParentClass> {
Map<String, T> getPlayers();
}
I have a bunch of entity type factories that derive from a common, generic interface. For instance,
public class ConnectionFactory implements IEntityFactory<Connection> { ... }
I'd like to use Google-Guice to break hard dependencies on these factories.
However, there's a syntax error when I try to configure Guice:
public class EntityFactoryModule extends AbstractModule {
#Override
protected void configure() {
bind(IEntityFactory<Connection>.class).to(ConnectionFactory.class);
}
}
Eclipse says "IEntityFactory cannot be resolved to a variable."
Can someone please help me understand why this doesn't work? Also, is there an alternate syntax that will work?
My Guice-fu is generally limited, but I think you want a type literal here:
bind(new TypeLiteral<IEntityFactory<Connection>>() {})
.to(ConnectionFactory.class);
One method is to declare a new interface:
interface IConnectionFactory extends IEntityFactory<Connection> { ...}
Then I can do:
bind(IConnectionFactory.class).to(ConnectionFactory.class);
But, there's already an interface explosion going on in my project.
Is there a better way?
Imagine you are working on a mature product and a new search feature is requested that is required for 50% of your product. Now assuming you have an established interface inheritance relationship with SomeDao that you don't want to break...
public interface MoneyDao
extends SomeDao<MoneyEntity>
{
//Operation common in much of the application
List<MoneyEntity> findByCriteria(MoneyCriteria criteria);
}
...is there a way to expose the method 'findByCriteria(..)' without repeating it in all the other places similar to MoneyDao where it's required in a cleaner way?
Bare in mind I want to avoid casting in to a new type where its used and modifying SomeDao if at all possible.
Regards,
James
Can you break the findByCriteria into its own interface and extend it in MoneyDao? Something like this:
public interface MoneyDao
extends SomeDao<MoneyEntity>, MoneyFinder
{
}
public interface MoneyFinder
{
//Operation common in much of the application
List<MoneyEntity> findByCriteria(MoneyCriteria criteria);
}
Now your class(es) implementing MoneyDao don't need to change, but you can pass around just the findByCriteria using MoneyFinder.
Its all depends on if you want a class that is searchable and is a Dao, in other words its if your Searchable class must also be a Dao. If its this case I would use a generic approach to make your Dao Searchable.
interface SearchableDao<Entity, Criteria> extends SomeDao<Entity>
{
List<Entity> findByCriteria(Criteria criteria);
}
Now your class can be a simple Dao or a SearchableDao. SearchableDao is also a simple Dao.
class MoneyDao implements SearchableDao<MoneyEntity, MoneyCriteria>
{
List<MoneyEntity> findByCriteria(MoneyCriteria criteria) {...}
}
I'm working on something that might benefit from a pattern like the following:
public abstract class SomeBuisnessThingy()
{
protected int someDatapoint;
}
public class ADatabaseThingy() extends SomeBusinessThingy()
{
#SomeJPAAnnotation
???? someDatapoint;
}
public class AWebServiceThingy() extends SomeBusinessThingy()
{
#SomeSOAPStuff
???? someDatapoint;
}
It smells more like an interface than an abstract class, but the same thing needs to be done. I have a DB implementation of that class and a WS implementation of that class.
Those representations are very similar, but may be different. For example the WS class may expose a field as a String so a 3rd party can easily do an integration, it can also be splot into its own package so we can hand a customer some lightweight WebService or POJO classes without all the baggage of the DB or a JPA framework coming with it. Perhaps it could be used to create the basic classes needed for something then switch between persistence frameworks that use different annotations.
Is it possible to ADD annotations to inherited fields?
No. If you need to annotate inherited members, you need to annotate the methods, not the fields.