0

Interface with Exception extends interface without exception

Hay,

I have a User-Table with the unique field email, which serves as username. Now when i call the dao.create method twice with the same information, i get an org.springframework.dao.DataIntegrityViolationException (Duplicate entry....). This brings me to the point, where i want my userDao.create(o) to throw a checked exception. Now i have the problem, that my UserDao-Interface extends the GenericDao-Interface, which already defines the create method without the throw-clause.

Since an extending interface can't throw more exceptions than the interface which it is extending, this code doesn't compile:

public interface GenericDao<T, PK extends Serializable> {
    /...
    T create(T object);
    /...
}

public interface UserDao extends GenericDao<User, Long> {
        /...
    User create(User user) throws UserExistsException;
    /...
}

(For why this is the cause see: Java interface extends questions (answer from cletus))

Now my question: What is the best practice to solve this problem?

Thank you very much for your answers in advance =)


PS: So far i have come up with a couple of answers, which don't really satisfy me. For one i could let GenericDao throw a checked exception, but since aproximatly 99% of tables dont have a unique-field (other than the pk) this isn't acceptable. Making UserExistsException a Runtime-Exception and document it seams not very nice either since i want to force the user of the method to catch the exception and report it to the enduser. Creating a new userDao.createUser()-method that throws the Exeption and throwing an UnsupportedOperationException with the already existing userDao.create()-method seams to me to be the tidiest of all solutions which came to my mind so far. I still would love to know, what is the proper way to solve this problem?

Community
  • 1
  • 1
  • why you are looking for a method with same name in UserDAO.? – TKV May 04 '12 at 09:17
  • I personally would definitely not make the interface method declare any exceptions. Whether you make it into a `RuntimeException` or force the caller to catch and handle is entirely specific to the business-logic semantics of that exception. – Marko Topolnik May 04 '12 at 09:18
  • Transposing the behavior of a [Set#add](http://docs.oracle.com/javase/7/docs/api/java/util/Set.html#add%28E%29) for example, it could be `boolean create(T object)` and return true if succesfully created, false if the user already exists. – assylias May 04 '12 at 09:18
  • @Tijo K Varghese I'm fairly new to Java and initialy i wanted to throw a checked Exception with the create-method of UserDao but not with the create-method of GenericDao. Because of that i tried to redefine the method. – TomKeller May 04 '12 at 10:20
  • @Marko Topolnik Thank you for your insight. I decided, at least until i hear a better solution, to provide a validateUserForCreation()-method and let userDao.create throw RuntimeExceptions. – TomKeller May 04 '12 at 10:25
  • force the caller function to make it catchable – TKV May 04 '12 at 10:25

1 Answers1

1

I suggest:

public interface GenericDao<T, PK extends Serializable> {
    /...
    T create(T object) throws DaoException;
    /...
}

DaoException is a (perhaps abstract) class, and UserExistsException extends DaoException.

Pablo
  • 3,655
  • 2
  • 30
  • 44
  • thank you for your suggestion. I personally don't really like that approach though, since it forces people who use implementations of GenericDao's create-method to catch an exeption even though the implementation doesn't throw one. But still: Thank you =) – TomKeller May 04 '12 at 10:33
  • @TomKeller It's true that it forces them to catch the exception, so it depends of what implementations do you expect to program. Do you expect to implement any that can't throw exceptions when you create a new DAO? In my experience, that's not usually the case. – Pablo May 04 '12 at 10:41