4

I have found myself in the need to override a static method, simply because it makes most sense, but I also know this is not possible.

The superclass, Entity.java:

abstract public class Entity<T> {
    public Entity() {
        //set up database connection
    }

    abstract public static Map<Object, T> getAll();

    abstract public void insert();

    abstract public void update();

    protected void getData(final String query) {
        //get data via database
    }

    protected void executeQuery(final String query) {
        //execute sql query on database
    }
}

One of the many concrete implementations, Account.java:

public class Account extends Entity<Account> {
    private final static String ALL_QUERY = "SELECT * FROM accounts";
    private final static String INSERT_QUERY = "INSERT INTO accounts (username, password) VALUES(?, ?)";
    private final static String UPDATE_QUERY = "UPDATE accounts SET password=? WHERE username=?";

    private String username;
    private String password;

    public Account(final String username, final String password) {
        this.username = username;
        this.password =  password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    @Override
    public static Map<Object, Account> getAll() {
        //return a map using the ALL_QUERY string, calls getData(string);
    }

    @Override
    public void insert() {
        //insert this using INSERT_QUERY, calls executeQuery(string);
    }

    @Override
    public void update() {
        //update this using UPDATE_QUERY, calls executeQuery(string);
    }
}

I haven't been going in depth explaining the code, but any general feedback on it would also be appreciated, I hope the comments explain enough.

So basically I think we can all agree that using Account.getAll() makes more sense over new Account().getAll() (if I would introduce a dummy syntax for it). However I do want to have it extend the Entity class, currently it is only for convienience, but later on I may have to use sets/lists/multisets of Entity and perform an update() action on all of them, for example if I would build some queue that performances all updates every minute.

So well, is there a way to construct getAll() correctly?

Regards.

8
  • Just remove the @Override on the static method, and you're fine. See also: stackoverflow.com/q/548861/139010 Commented May 13, 2013 at 19:52
  • Thankyou for using my suggestions. Not marking the answer you used as correct might lead other attention to your original question though. Commented May 13, 2013 at 19:52
  • @MattBall Implementation wise it is fine indeed. But I rather have some harsher restrictions, that is the reason I mention it in the interface in the first place. @ChrisCooney Probably that's some lag as I did mark it as correct, I hope I've used your suggestions correctly, especially with the generic argument Entity<T> Commented May 13, 2013 at 19:55
  • 3
    Read up on Martin Fowler's Table Data Gateway and Data Mapper patterns. You should also read up on Data Access Objects. Remove persistence data from your POJOs. Commented May 13, 2013 at 19:59
  • How can getAll abstract and static in Entity? Commented May 13, 2013 at 20:21

2 Answers 2

1

You could have separate classes for operations on all elements:

abstract public class Collection<T extends Entity<T>> {
    abstract public static List<T> getAll();
    public void printAll() {
        // Print all entries of List obtained from getAll()
    }
}

Which you could use as:

public class Accounts extends Collection<Account> {
    @Override
    public List<Account> getAll() {
        //return a list using the ALL_QUERY string, calls getData(string);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

It's not a Collection, it's a Data Access Object/Service. (Or, as the answer below called it, a Repository). Usage, API & functionality are quite quite different from Java or other collections.
I just called it Collection for lack of a better name, a name that doesn't interfere with existing collection classes would indeed be better.
1

It doesn't seems to me that it is really "simply because it makes most sense".

Tying persistence at your entity is not a good idea. There are already lots of patterns that give an appropriate design on this problem.

For example, in Domain Driven Design, "Persistence Ignorance" is what people trying to achieve. Consider making a Repository for each of your entity:

interface Repository<T> {
    List<T> findAll();
    void insert(T);
    void update(T);
}

so you can override it by whatever way you want:

interface UserRepository extends Repository<User> {
    // some other methods which is meaningful for User
    User findByLoginName(String loginName);
}


class UserRepositoryImpl implements UserRepository {
    List<User> findAll() {
         // call whatever query
    }
    void insert(T){...}
    void update(T){...}
    User findByLoginName(String loginName) {...}
}

With a proper design and a component to handle the retrieval/storage of entity, you can have a less-persistence-coupled entity, and with repository that can perform proper "overriding".

2 Comments

I quite like "Repository" for the naming (thanks Adrian!). I'd +1'd this answer, but in general I would recommend using Hibernate rather than spending 2 man-years writing a persistence layer. Wrinkles & traps aplenty, if you try to DIY this..
@ThomasW You know what? A lot of people is using Hibernate in implementing repositories :) And, take a look in Spring Data - Hibernate, which makes creating Repository a breeze :) Hibernate is easy to use, but it doesn't mean that it is fine to pollute the entities with persistence logics (which use Hibernate)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.