diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java
index 16db42433580ec2d1ced4da85b1cfc0954017d4a..49297579d48ab90dbfefeff778afce060688eb3c 100644
--- a/src/main/java/de/thm/arsnova/config/AppConfig.java
+++ b/src/main/java/de/thm/arsnova/config/AppConfig.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.SerializationFeature;
 import de.thm.arsnova.ImageUtils;
 import de.thm.arsnova.connector.client.ConnectorClient;
 import de.thm.arsnova.connector.client.ConnectorClientImpl;
+import de.thm.arsnova.entities.Answer;
 import de.thm.arsnova.entities.Comment;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.LogEntry;
@@ -32,12 +33,14 @@ import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.serialization.CouchDbDocumentModule;
 import de.thm.arsnova.entities.serialization.CouchDbObjectMapperFactory;
 import de.thm.arsnova.entities.serialization.View;
+import de.thm.arsnova.persistance.AnswerRepository;
 import de.thm.arsnova.persistance.CommentRepository;
 import de.thm.arsnova.persistance.ContentRepository;
 import de.thm.arsnova.persistance.LogEntryRepository;
 import de.thm.arsnova.persistance.MotdRepository;
 import de.thm.arsnova.persistance.SessionRepository;
 import de.thm.arsnova.persistance.UserRepository;
+import de.thm.arsnova.persistance.couchdb.CouchDbAnswerRepository;
 import de.thm.arsnova.persistance.couchdb.CouchDbCommentRepository;
 import de.thm.arsnova.persistance.couchdb.CouchDbContentRepository;
 import de.thm.arsnova.persistance.couchdb.CouchDbLogEntryRepository;
@@ -308,6 +311,11 @@ public class AppConfig extends WebMvcConfigurerAdapter {
 		return new CouchDbContentRepository(Content.class, couchDbConnector(), false);
 	}
 
+	@Bean
+	public AnswerRepository answerRepository() throws Exception {
+		return new CouchDbAnswerRepository(Answer.class, couchDbConnector(), false);
+	}
+
 	@Bean
 	public UserRepository userRepository() throws Exception {
 		return new CouchDbUserRepository(DbUser.class, couchDbConnector(), false);
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 72ff1ff4fcd1d3ba34af724462c45112e8cc77fc..247d432cb39afe0ed21a8f73f98af00258c2be7e 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -25,9 +25,6 @@ import com.google.common.collect.Lists;
 import de.thm.arsnova.connector.model.Course;
 import de.thm.arsnova.domain.CourseScore;
 import de.thm.arsnova.entities.*;
-import de.thm.arsnova.entities.transport.AnswerQueueElement;
-import de.thm.arsnova.events.NewAnswerEvent;
-import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.persistance.ContentRepository;
 import de.thm.arsnova.persistance.LogEntryRepository;
 import de.thm.arsnova.persistance.MotdRepository;
@@ -41,25 +38,18 @@ import org.slf4j.LoggerFactory;
 import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.ApplicationEventPublisherAware;
 import org.springframework.context.annotation.Profile;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
-import java.util.AbstractMap;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 /**
  * Database implementation based on CouchDB.
@@ -81,7 +71,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
  */
 @Profile("!test")
 @Service("databaseDao")
-public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware {
+public class CouchDBDao implements IDatabaseDao {
 
 	private static final int BULK_PARTITION_SIZE = 500;
 
@@ -105,10 +95,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 	private String databaseName;
 	private Database database;
 
-	private ApplicationEventPublisher publisher;
-
-	private final Queue<AbstractMap.SimpleEntry<Document, AnswerQueueElement>> answerQueue = new ConcurrentLinkedQueue<>();
-
 	private static final Logger logger = LoggerFactory.getLogger(CouchDBDao.class);
 
 	@Value("${couchdb.host}")
@@ -142,11 +128,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		return this;
 	}
 
-	@Override
-	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
-		this.publisher = publisher;
-	}
-
 	private Database getDatabase() {
 		if (database == null) {
 			try {
@@ -169,61 +150,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		getDatabase().deleteDocument(d);
 	}
 
-	@CacheEvict("answers")
-	@Override
-	public int deleteAnswers(final Content content) {
-		try {
-			final View view = new View("answer/by_questionid");
-			view.setKey(content.getId());
-			view.setIncludeDocs(true);
-			final ViewResults results = getDatabase().view(view);
-			final List<List<Document>> partitions = Lists.partition(results.getResults(), BULK_PARTITION_SIZE);
-
-			int count = 0;
-			for (List<Document> partition: partitions) {
-				List<Document> answersToDelete = new ArrayList<>();
-				for (final Document a : partition) {
-					final Document d = new Document(a.getJSONObject("doc"));
-					d.put("_deleted", true);
-					answersToDelete.add(d);
-				}
-				if (database.bulkSaveDocuments(answersToDelete.toArray(new Document[answersToDelete.size()]))) {
-					count += partition.size();
-				} else {
-					logger.error("Could not bulk delete answers.");
-				}
-			}
-			dbLogger.log("delete", "type", "answer", "answerCount", count);
-
-			return count;
-		} catch (final IOException e) {
-			logger.error("Could not delete answers for content {}.", content.getId(), e);
-		}
-
-		return 0;
-	}
-
-	@Override
-	public Answer getMyAnswer(final User me, final String questionId, final int piRound) {
-
-		final View view = new View("answer/doc_by_questionid_user_piround");
-		if (2 == piRound) {
-			view.setKey(questionId, me.getUsername(), "2");
-		} else {
-			/* needed for legacy questions whose piRound property has not been set */
-			view.setStartKey(questionId, me.getUsername());
-			view.setEndKey(questionId, me.getUsername(), "1");
-		}
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return null;
-		}
-		return (Answer) JSONObject.toBean(
-				results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
-				Answer.class
-				);
-	}
-
 	@SuppressWarnings("unchecked")
 	@Override
 	public <T> T getObjectFromId(final String documentId, final Class<T> klass) {
@@ -239,176 +165,10 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		}
 	}
 
-	@Override
-	public List<Answer> getAnswers(final Content content, final int piRound) {
-		final String questionId = content.getId();
-		final View view = new View("answer/by_questionid_piround_text_subject");
-		if (2 == piRound) {
-			view.setStartKey(questionId, 2);
-			view.setEndKey(questionId, 2, "{}");
-		} else {
-			/* needed for legacy questions whose piRound property has not been set */
-			view.setStartKeyArray(questionId);
-			view.setEndKeyArray(questionId, 1, "{}");
-		}
-		view.setGroup(true);
-		final ViewResults results = getDatabase().view(view);
-		final int abstentionCount = getDatabaseDao().getAbstentionAnswerCount(questionId);
-		final List<Answer> answers = new ArrayList<>();
-
-		for (final Document d : results.getResults()) {
-			final Answer a = new Answer();
-			a.setAnswerCount(d.getInt("value"));
-			a.setAbstentionCount(abstentionCount);
-			a.setQuestionId(d.getJSONObject().getJSONArray("key").getString(0));
-			a.setPiRound(piRound);
-			final String answerText = d.getJSONObject().getJSONArray("key").getString(3);
-			a.setAnswerText("null".equals(answerText) ? null : answerText);
-			answers.add(a);
-		}
-		return answers;
-	}
-
-	@Override
-	public List<Answer> getAllAnswers(final Content content) {
-		final String questionId = content.getId();
-		final View view = new View("answer/by_questionid_piround_text_subject");
-		view.setStartKeyArray(questionId);
-		view.setEndKeyArray(questionId, "{}");
-		view.setGroup(true);
-		final ViewResults results = getDatabase().view(view);
-		final int abstentionCount = getDatabaseDao().getAbstentionAnswerCount(questionId);
-
-		final List<Answer> answers = new ArrayList<>();
-		for (final Document d : results.getResults()) {
-			final Answer a = new Answer();
-			a.setAnswerCount(d.getInt("value"));
-			a.setAbstentionCount(abstentionCount);
-			a.setQuestionId(d.getJSONObject().getJSONArray("key").getString(0));
-			final String answerText = d.getJSONObject().getJSONArray("key").getString(3);
-			final String answerSubject = d.getJSONObject().getJSONArray("key").getString(4);
-			final boolean successfulFreeTextAnswer = d.getJSONObject().getJSONArray("key").getBoolean(5);
-			a.setAnswerText("null".equals(answerText) ? null : answerText);
-			a.setAnswerSubject("null".equals(answerSubject) ? null : answerSubject);
-			a.setSuccessfulFreeTextAnswer(successfulFreeTextAnswer);
-			answers.add(a);
-		}
-		return answers;
-	}
-
-	@Cacheable("answers")
-	@Override
-	public List<Answer> getAnswers(final Content content) {
-		return this.getAnswers(content, content.getPiRound());
-	}
-
-	@Override
-	public int getAbstentionAnswerCount(final String questionId) {
-		final View view = new View("answer/by_questionid_piround_text_subject");
-		view.setStartKeyArray(questionId);
-		view.setEndKeyArray(questionId, "{}");
-		view.setGroup(true);
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return 0;
-		}
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
-	}
-
-	@Override
-	public int getAnswerCount(final Content content, final int piRound) {
-		final View view = new View("answer/by_questionid_piround_text_subject");
-		view.setStartKey(content.getId(), piRound);
-		view.setEndKey(content.getId(), piRound, "{}");
-		view.setGroup(true);
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return 0;
-		}
-
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
-	}
-
-	@Override
-	public int getTotalAnswerCountByQuestion(final Content content) {
-		final View view = new View("answer/by_questionid_piround_text_subject");
-		view.setStartKeyArray(content.getId());
-		view.setEndKeyArray(content.getId(), "{}");
-		view.setGroup(true);
-		final ViewResults results = getDatabase().view(view);
-
-		if (results.getResults().isEmpty()) {
-			return 0;
-		}
-
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
-	}
-
 	private boolean isEmptyResults(final ViewResults results) {
 		return results == null || results.getResults().isEmpty() || results.getJSONArray("rows").isEmpty();
 	}
 
-	@Override
-	public List<Answer> getFreetextAnswers(final String questionId, final int start, final int limit) {
-		final List<Answer> answers = new ArrayList<>();
-		final View view = new View("answer/doc_by_questionid_timestamp");
-		if (start > 0) {
-			view.setSkip(start);
-		}
-		if (limit > 0) {
-			view.setLimit(limit);
-		}
-		view.setDescending(true);
-		view.setStartKeyArray(questionId, "{}");
-		view.setEndKeyArray(questionId);
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return answers;
-		}
-		for (final Document d : results.getResults()) {
-			final Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
-			a.setQuestionId(questionId);
-			answers.add(a);
-		}
-		return answers;
-	}
-
-	@Override
-	public List<Answer> getMyAnswers(final User me, final Session s) {
-		final View view = new View("answer/doc_by_user_sessionid");
-		view.setKey(me.getUsername(), s.getId());
-		final ViewResults results = getDatabase().view(view);
-		final List<Answer> answers = new ArrayList<>();
-		if (results == null || results.getResults() == null || results.getResults().isEmpty()) {
-			return answers;
-		}
-		for (final Document d : results.getResults()) {
-			final Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
-			a.set_id(d.getId());
-			a.set_rev(d.getRev());
-			a.setUser(me.getUsername());
-			a.setSessionId(s.getId());
-			answers.add(a);
-		}
-		return answers;
-	}
-
-	@Override
-	public int getTotalAnswerCount(final String sessionKey) {
-		final Session s = sessionRepository.getSessionFromKeyword(sessionKey);
-		if (s == null) {
-			throw new NotFoundException();
-		}
-
-		final View view = new View("answer/by_sessionid_variant");
-		view.setKey(s.getId());
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return 0;
-		}
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
-	}
-
 	@Cacheable("statistics")
 	@Override
 	public Statistics getStatistics() {
@@ -487,100 +247,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		return stats;
 	}
 
-	@CacheEvict(value = "answers", key = "#content")
-	@Override
-	public Answer saveAnswer(final Answer answer, final User user, final Content content, final Session session) {
-		final Document a = new Document();
-		a.put("type", "skill_question_answer");
-		a.put("sessionId", answer.getSessionId());
-		a.put("questionId", answer.getQuestionId());
-		a.put("answerSubject", answer.getAnswerSubject());
-		a.put("questionVariant", answer.getQuestionVariant());
-		a.put("questionValue", answer.getQuestionValue());
-		a.put("answerText", answer.getAnswerText());
-		a.put("answerTextRaw", answer.getAnswerTextRaw());
-		a.put("successfulFreeTextAnswer", answer.isSuccessfulFreeTextAnswer());
-		a.put("timestamp", answer.getTimestamp());
-		a.put("user", user.getUsername());
-		a.put("piRound", answer.getPiRound());
-		a.put("abstention", answer.isAbstention());
-		a.put("answerImage", answer.getAnswerImage());
-		a.put("answerThumbnailImage", answer.getAnswerThumbnailImage());
-		AnswerQueueElement answerQueueElement = new AnswerQueueElement(session, content, answer, user);
-		this.answerQueue.offer(new AbstractMap.SimpleEntry<>(a, answerQueueElement));
-		return answer;
-	}
-
-	@Scheduled(fixedDelay = 5000)
-	public void flushAnswerQueue() {
-		final Map<Document, Answer> map = new HashMap<>();
-		final List<Document> answerList = new ArrayList<>();
-		final List<AnswerQueueElement> elements = new ArrayList<>();
-		AbstractMap.SimpleEntry<Document, AnswerQueueElement> entry;
-		while ((entry = this.answerQueue.poll()) != null) {
-			final Document doc = entry.getKey();
-			final Answer answer = entry.getValue().getAnswer();
-			map.put(doc, answer);
-			answerList.add(doc);
-			elements.add(entry.getValue());
-		}
-		if (answerList.isEmpty()) {
-			// no need to send an empty bulk request. ;-)
-			return;
-		}
-		try {
-			getDatabase().bulkSaveDocuments(answerList.toArray(new Document[answerList.size()]));
-			for (Document d : answerList) {
-				final Answer answer = map.get(d);
-				answer.set_id(d.getId());
-				answer.set_rev(d.getRev());
-			}
-			// Send NewAnswerEvents ...
-			for (AnswerQueueElement e : elements) {
-				this.publisher.publishEvent(new NewAnswerEvent(this, e.getSession(), e.getAnswer(), e.getUser(), e.getQuestion()));
-			}
-		} catch (IOException e) {
-			logger.error("Could not bulk save answers from queue.", e);
-		}
-	}
-
-	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
-	@CacheEvict(value = "answers", allEntries = true)
-	@Override
-	public Answer updateAnswer(final Answer answer) {
-		try {
-			final Document a = database.getDocument(answer.get_id());
-			a.put("answerSubject", answer.getAnswerSubject());
-			a.put("answerText", answer.getAnswerText());
-			a.put("answerTextRaw", answer.getAnswerTextRaw());
-			a.put("successfulFreeTextAnswer", answer.isSuccessfulFreeTextAnswer());
-			a.put("timestamp", answer.getTimestamp());
-			a.put("abstention", answer.isAbstention());
-			a.put("questionValue", answer.getQuestionValue());
-			a.put("answerImage", answer.getAnswerImage());
-			a.put("answerThumbnailImage", answer.getAnswerThumbnailImage());
-			a.put("read", answer.isRead());
-			database.saveDocument(a);
-			answer.set_rev(a.getRev());
-			return answer;
-		} catch (final IOException e) {
-			logger.error("Could not update answer {}.", answer, e);
-		}
-		return null;
-	}
-
-	/* TODO: Only evict cache entry for the answer's session. This requires some refactoring. */
-	@CacheEvict(value = "answers", allEntries = true)
-	@Override
-	public void deleteAnswer(final String answerId) {
-		try {
-			database.deleteDocument(database.getDocument(answerId));
-			dbLogger.log("delete", "type", "answer");
-		} catch (final IOException e) {
-			logger.error("Could not delete answer {}.", answerId, e);
-		}
-	}
-
 	/**
 	 * Adds convenience methods to CouchDB4J's view class.
 	 */
@@ -651,119 +317,6 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		return 0;
 	}
 
-	@Override
-	public int countLectureQuestionAnswers(final Session session) {
-		return countQuestionVariantAnswers(session, "lecture");
-	}
-
-	@Override
-	public int countPreparationQuestionAnswers(final Session session) {
-		return countQuestionVariantAnswers(session, "preparation");
-	}
-
-	private int countQuestionVariantAnswers(final Session session, final String variant) {
-		final View view = new View("answer/by_sessionid_variant");
-		view.setKey(session.getId(), variant);
-		view.setReduce(true);
-		final ViewResults results = getDatabase().view(view);
-		if (results.getResults().isEmpty()) {
-			return 0;
-		}
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
-	}
-
-	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
-	@CacheEvict(value = "answers", allEntries = true)
-	@Override
-	public int deleteAllQuestionsAnswers(final Session session) {
-		final List<Content> contents = contentRepository.getQuestions(session.getId());
-		contentRepository.resetQuestionsRoundState(session, contents);
-
-		return deleteAllAnswersForQuestions(contents);
-	}
-
-	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
-	@CacheEvict(value = "answers", allEntries = true)
-	@Override
-	public int deleteAllPreparationAnswers(final Session session) {
-		final List<Content> contents = contentRepository.getQuestions(session.getId(), "preparation");
-		contentRepository.resetQuestionsRoundState(session, contents);
-
-		return deleteAllAnswersForQuestions(contents);
-	}
-
-	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
-	@CacheEvict(value = "answers", allEntries = true)
-	@Override
-	public int deleteAllLectureAnswers(final Session session) {
-		final List<Content> contents = contentRepository.getQuestions(session.getId(), "lecture");
-		contentRepository.resetQuestionsRoundState(session, contents);
-
-		return deleteAllAnswersForQuestions(contents);
-	}
-
-	public int deleteAllAnswersForQuestions(List<Content> contents) {
-		List<String> questionIds = new ArrayList<>();
-		for (Content q : contents) {
-			questionIds.add(q.getId());
-		}
-		final View bulkView = new View("answer/by_questionid");
-		bulkView.setKeys(questionIds);
-		bulkView.setIncludeDocs(true);
-		final List<Document> result = getDatabase().view(bulkView).getResults();
-		final List<Document> allAnswers = new ArrayList<>();
-		for (Document a : result) {
-			final Document d = new Document(a.getJSONObject("doc"));
-			d.put("_deleted", true);
-			allAnswers.add(d);
-		}
-		try {
-			getDatabase().bulkSaveDocuments(allAnswers.toArray(new Document[allAnswers.size()]));
-
-			return allAnswers.size();
-		} catch (IOException e) {
-			logger.error("Could not bulk delete answers.", e);
-		}
-
-		return 0;
-	}
-
-	public int[] deleteAllAnswersWithQuestions(List<Content> contents) {
-		List<String> questionIds = new ArrayList<>();
-		final List<Document> allQuestions = new ArrayList<>();
-		for (Content q : contents) {
-			final Document d = new Document();
-			d.put("_id", q.getId());
-			d.put("_rev", q.getRevision());
-			d.put("_deleted", true);
-			questionIds.add(q.getId());
-			allQuestions.add(d);
-		}
-		final View bulkView = new View("answer/by_questionid");
-		bulkView.setKeys(questionIds);
-		bulkView.setIncludeDocs(true);
-		final List<Document> result = getDatabase().view(bulkView).getResults();
-
-		final List<Document> allAnswers = new ArrayList<>();
-		for (Document a : result) {
-			final Document d = new Document(a.getJSONObject("doc"));
-			d.put("_deleted", true);
-			allAnswers.add(d);
-		}
-
-		try {
-			List<Document> deleteList = new ArrayList<>(allAnswers);
-			deleteList.addAll(allQuestions);
-			getDatabase().bulkSaveDocuments(deleteList.toArray(new Document[deleteList.size()]));
-
-			return new int[] {deleteList.size(), result.size()};
-		} catch (IOException e) {
-			logger.error("Could not bulk delete contents and answers.", e);
-		}
-
-		return new int[] {0, 0};
-	}
-
 	@Cacheable("learningprogress")
 	@Override
 	public CourseScore getLearningProgress(final Session session) {
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 532729fdf3fc8d101a9c2700b350209c5876c5f2..8337277a7d243e8857e89c04d1f76fbb548dabb4 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -26,48 +26,11 @@ import java.util.List;
  * All methods the database must support.
  */
 public interface IDatabaseDao {
-	Answer getMyAnswer(User me, String questionId, int piRound);
-
-	List<Answer> getAnswers(Content content, int piRound);
-
-	List<Answer> getAnswers(Content content);
-
-	List<Answer> getAllAnswers(Content content);
-
-	int getAnswerCount(Content content, int piRound);
-
-	int getTotalAnswerCountByQuestion(Content content);
-
-	int getAbstentionAnswerCount(String questionId);
-
-	List<Answer> getFreetextAnswers(String questionId, final int start, final int limit);
-
-	List<Answer> getMyAnswers(User me, Session session);
-
-	int getTotalAnswerCount(String sessionKey);
-
-	int deleteAnswers(Content content);
-
-	Answer saveAnswer(Answer answer, User user, Content content, Session session);
-
-	Answer updateAnswer(Answer answer);
-
-	void deleteAnswer(String answerId);
 
 	int deleteInactiveGuestVisitedSessionLists(long lastActivityBefore);
 
-	int countLectureQuestionAnswers(Session session);
-
-	int countPreparationQuestionAnswers(Session session);
-
-	int deleteAllQuestionsAnswers(Session session);
-
 	CourseScore getLearningProgress(Session session);
 
-	int deleteAllPreparationAnswers(Session session);
-
-	int deleteAllLectureAnswers(Session session);
-
 	Statistics getStatistics();
 
 	<T> T getObjectFromId(String documentId, Class<T> klass);
@@ -75,6 +38,4 @@ public interface IDatabaseDao {
 	MotdList getMotdListForUser(final String username);
 
 	MotdList createOrUpdateMotdList(MotdList motdlist);
-
-	int[] deleteAllAnswersWithQuestions(List<Content> contents);
 }
diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java
index 283060bb155cd307944bb5b7037f428bfadd2708..146acaf85f960b692c825dc7baf2b4f5f0fafc54 100644
--- a/src/main/java/de/thm/arsnova/entities/Answer.java
+++ b/src/main/java/de/thm/arsnova/entities/Answer.java
@@ -18,6 +18,8 @@
 package de.thm.arsnova.entities;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonView;
+import de.thm.arsnova.entities.serialization.View;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -29,10 +31,9 @@ import java.io.Serializable;
  * This class has additional fields to transport generated answer statistics.
  */
 @ApiModel(value = "Answer", description = "the answer entity")
-public class Answer implements Serializable {
-
-	private String _id;
-	private String _rev;
+public class Answer implements Entity {
+	private String id;
+	private String rev;
 	private String type;
 	private String sessionId;
 	private String questionId;
@@ -58,143 +59,158 @@ public class Answer implements Serializable {
 	}
 
 	@ApiModelProperty(required = true, value = "the couchDB ID")
-	public final String get_id() {
-		return _id;
-	}
-
-	public final void set_id(String _id) {
-		this._id = _id;
-	}
-
-	public final String get_rev() {
-		return _rev;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public String getId() {
+		return id;
 	}
 
-	public final void set_rev(final String _rev) {
-		this._rev = _rev;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public void setId(final String id) {
+		this.id = id;
 	}
 
-	@ApiModelProperty(required = true, value = "\"skill_question_answer\" - used to filter in the couchDB")
-	public final String getType() {
-		return type;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public void setRevision(final String rev) {
+		this.rev = rev;
 	}
 
-	public final void setType(final String type) {
-		this.type = type;
+	@JsonView({View.Persistence.class, View.Public.class})
+	public String getRevision() {
+		return rev;
 	}
 
 	@ApiModelProperty(required = true, value = "ID of the session, the answer is assigned to")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final String getSessionId() {
 		return sessionId;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setSessionId(final String sessionId) {
 		this.sessionId = sessionId;
 	}
 
 	@ApiModelProperty(required = true, value = "used to display question id")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final String getQuestionId() {
 		return questionId;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setQuestionId(final String questionId) {
 		this.questionId = questionId;
 	}
 
 	@ApiModelProperty(required = true, value = "the answer text")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final String getAnswerText() {
 		return answerText;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setAnswerText(final String answerText) {
 		this.answerText = answerText;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final String getAnswerTextRaw() {
 		return this.answerTextRaw;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setAnswerTextRaw(final String answerTextRaw) {
 		this.answerTextRaw = answerTextRaw;
 	}
 
 	@ApiModelProperty(required = true, value = "the answer subject")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final String getAnswerSubject() {
 		return answerSubject;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setAnswerSubject(final String answerSubject) {
 		this.answerSubject = answerSubject;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final boolean isSuccessfulFreeTextAnswer() {
 		return this.successfulFreeTextAnswer;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public final void setSuccessfulFreeTextAnswer(final boolean successfulFreeTextAnswer) {
 		this.successfulFreeTextAnswer = successfulFreeTextAnswer;
 	}
 
 	@ApiModelProperty(required = true, value = "the peer instruction round nr.")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public int getPiRound() {
 		return piRound;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setPiRound(int piRound) {
 		this.piRound = piRound;
 	}
 
-	/* TODO: use JsonViews instead of JsonIgnore when supported by Spring (4.1)
-	 * http://wiki.fasterxml.com/JacksonJsonViews
-	 * https://jira.spring.io/browse/SPR-7156 */
 	@ApiModelProperty(required = true, value = "the user")
-	@JsonIgnore
+	@JsonView(View.Persistence.class)
 	public final String getUser() {
 		return user;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
+	public final void setUser(final String user) {
+		this.user = user;
+	}
+
 	@ApiModelProperty(required = true, value = "the answer image")
-	@JsonIgnore
+	@JsonView(View.Persistence.class)
 	public String getAnswerImage() {
 		return answerImage;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setAnswerImage(String answerImage) {
 		this.answerImage = answerImage;
 	}
 
 	@ApiModelProperty(required = true, value = "the answer thumbnail")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getAnswerThumbnailImage() {
 		return answerThumbnailImage;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setAnswerThumbnailImage(String answerThumbnailImage) {
 		this.answerThumbnailImage = answerThumbnailImage;
 	}
 
-	public final void setUser(final String user) {
-		this.user = user;
-	}
-
 	@ApiModelProperty(required = true, value = "the creation date timestamp")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public long getTimestamp() {
 		return timestamp;
 	}
 
+	@JsonView(View.Persistence.class)
 	public void setTimestamp(long timestamp) {
 		this.timestamp = timestamp;
 	}
 
 	@ApiModelProperty(required = true, value = "displays whether the answer is read")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public boolean isRead() {
 		return read;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setRead(boolean read) {
 		this.read = read;
 	}
 
 	@ApiModelProperty(required = true, value = "the number of answers given. used for statistics")
+	@JsonView(View.Public.class)
 	public final int getAnswerCount() {
 		return answerCount;
 	}
@@ -204,15 +220,18 @@ public class Answer implements Serializable {
 	}
 
 	@ApiModelProperty(required = true, value = "the abstention")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public boolean isAbstention() {
 		return abstention;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setAbstention(boolean abstention) {
 		this.abstention = abstention;
 	}
 
 	@ApiModelProperty(required = true, value = "the number of abstentions given. used for statistics")
+	@JsonView(View.Public.class)
 	public int getAbstentionCount() {
 		return abstentionCount;
 	}
@@ -222,19 +241,23 @@ public class Answer implements Serializable {
 	}
 
 	@ApiModelProperty(required = true, value = "either lecture or preparation")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public String getQuestionVariant() {
 		return questionVariant;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setQuestionVariant(String questionVariant) {
 		this.questionVariant = questionVariant;
 	}
 
 	@ApiModelProperty(required = true, value = "used to display question value")
+	@JsonView({View.Persistence.class, View.Public.class})
 	public int getQuestionValue() {
 		return questionValue;
 	}
 
+	@JsonView({View.Persistence.class, View.Public.class})
 	public void setQuestionValue(int questionValue) {
 		this.questionValue = questionValue;
 	}
@@ -255,8 +278,8 @@ public class Answer implements Serializable {
 		// auto generated!
 		final int prime = 31;
 		int result = 1;
-		result = prime * result + ((_id == null) ? 0 : _id.hashCode());
-		result = prime * result + ((_rev == null) ? 0 : _rev.hashCode());
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result + ((rev == null) ? 0 : rev.hashCode());
 		result = prime * result + ((answerSubject == null) ? 0 : answerSubject.hashCode());
 		result = prime * result + ((answerText == null) ? 0 : answerText.hashCode());
 		result = prime * result + piRound;
@@ -280,18 +303,18 @@ public class Answer implements Serializable {
 			return false;
 		}
 		Answer other = (Answer) obj;
-		if (_id == null) {
-			if (other._id != null) {
+		if (id == null) {
+			if (other.id != null) {
 				return false;
 			}
-		} else if (!_id.equals(other._id)) {
+		} else if (!id.equals(other.id)) {
 			return false;
 		}
-		if (_rev == null) {
-			if (other._rev != null) {
+		if (rev == null) {
+			if (other.rev != null) {
 				return false;
 			}
-		} else if (!_rev.equals(other._rev)) {
+		} else if (!rev.equals(other.rev)) {
 			return false;
 		}
 		if (answerSubject == null) {
diff --git a/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java b/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
index 7141f02f45cbebeabb7ee15e38aa25b2087f0975..3a3c6c1ebd72cf4603c06c3b06043afce76366c9 100644
--- a/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
+++ b/src/main/java/de/thm/arsnova/entities/serialization/CouchDbTypeFieldConverter.java
@@ -20,6 +20,7 @@ package de.thm.arsnova.entities.serialization;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 import com.fasterxml.jackson.databind.util.Converter;
+import de.thm.arsnova.entities.Answer;
 import de.thm.arsnova.entities.Comment;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.Entity;
@@ -41,6 +42,7 @@ public class CouchDbTypeFieldConverter implements Converter<Class<? extends Enti
 		typeMapping.put(Session.class, "session");
 		typeMapping.put(Comment.class, "interposed_question");
 		typeMapping.put(Content.class, "skill_question");
+		typeMapping.put(Answer.class, "skill_question_answer");
 	}
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java b/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..27693fa2b45a20be0526e70078d2d278f40422aa
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2017 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.persistance;
+
+import de.thm.arsnova.entities.Answer;
+import de.thm.arsnova.entities.Content;
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+
+import java.util.List;
+
+public interface AnswerRepository {
+	Answer get(String id);
+	Answer getMyAnswer(User me, String questionId, int piRound);
+	List<Answer> getAnswers(Content content, int piRound);
+	List<Answer> getAnswers(Content content);
+	List<Answer> getAllAnswers(Content content);
+	int getAnswerCount(Content content, int piRound);
+	int getTotalAnswerCountByQuestion(Content content);
+	int getAbstentionAnswerCount(String questionId);
+	List<Answer> getFreetextAnswers(String questionId, final int start, final int limit);
+	List<Answer> getMyAnswers(User me, Session session);
+	int getTotalAnswerCount(String sessionKey);
+	int deleteAnswers(Content content);
+	Answer saveAnswer(Answer answer, User user, Content content, Session session);
+	Answer updateAnswer(Answer answer);
+	void deleteAnswer(String answerId);
+	int countLectureQuestionAnswers(Session session);
+	int countPreparationQuestionAnswers(Session session);
+	int deleteAllQuestionsAnswers(Session session);
+	int deleteAllPreparationAnswers(Session session);
+	int deleteAllLectureAnswers(Session session);
+	int[] deleteAllAnswersWithQuestions(List<Content> contents);
+}
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ebb3273e4c7ba6deac9ecf6ecd9090d860d52d8
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java
@@ -0,0 +1,385 @@
+package de.thm.arsnova.persistance.couchdb;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Lists;
+import de.thm.arsnova.entities.Answer;
+import de.thm.arsnova.entities.Content;
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+import de.thm.arsnova.entities.transport.AnswerQueueElement;
+import de.thm.arsnova.events.NewAnswerEvent;
+import de.thm.arsnova.exceptions.NotFoundException;
+import de.thm.arsnova.persistance.AnswerRepository;
+import de.thm.arsnova.persistance.ContentRepository;
+import de.thm.arsnova.persistance.LogEntryRepository;
+import de.thm.arsnova.persistance.SessionRepository;
+import org.ektorp.BulkDeleteDocument;
+import org.ektorp.ComplexKey;
+import org.ektorp.CouchDbConnector;
+import org.ektorp.DbAccessException;
+import org.ektorp.DocumentOperationResult;
+import org.ektorp.UpdateConflictException;
+import org.ektorp.ViewResult;
+import org.ektorp.support.CouchDbRepositorySupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class CouchDbAnswerRepository extends CouchDbRepositorySupport<Answer> implements AnswerRepository, ApplicationEventPublisherAware {
+	private static final int BULK_PARTITION_SIZE = 500;
+	private static final Logger logger = LoggerFactory.getLogger(CouchDbAnswerRepository.class);
+
+	private final Queue<AnswerQueueElement> answerQueue = new ConcurrentLinkedQueue<>();
+
+	@Autowired
+	private LogEntryRepository dbLogger;
+
+	@Autowired
+	private SessionRepository sessionRepository;
+
+	@Autowired
+	private ContentRepository contentRepository;
+
+	private ApplicationEventPublisher publisher;
+
+	public CouchDbAnswerRepository(Class<Answer> type, CouchDbConnector db, boolean createIfNotExists) {
+		super(type, db, createIfNotExists);
+	}
+
+	@Scheduled(fixedDelay = 5000)
+	public void flushAnswerQueue() {
+		if (answerQueue.isEmpty()) {
+			// no need to send an empty bulk request.
+			return;
+		}
+
+		final List<Answer> answerList = new ArrayList<>();
+		final List<AnswerQueueElement> elements = new ArrayList<>();
+		AnswerQueueElement entry;
+		while ((entry = this.answerQueue.poll()) != null) {
+			final Answer answer = entry.getAnswer();
+			answerList.add(answer);
+			elements.add(entry);
+		}
+		try {
+			db.executeBulk(answerList);
+
+			// Send NewAnswerEvents ...
+			for (AnswerQueueElement e : elements) {
+				this.publisher.publishEvent(new NewAnswerEvent(this, e.getSession(), e.getAnswer(), e.getUser(), e.getQuestion()));
+			}
+		} catch (DbAccessException e) {
+			logger.error("Could not bulk save answers from queue.", e);
+		}
+	}
+
+	@Override
+	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+		this.publisher = publisher;
+	}
+
+	@CacheEvict("answers")
+	@Override
+	public int deleteAnswers(final Content content) {
+		try {
+			final ViewResult result = db.queryView(createQuery("by_questionid")
+					.key(content.getId()));
+			final List<List<ViewResult.Row>> partitions = Lists.partition(result.getRows(), BULK_PARTITION_SIZE);
+
+			int count = 0;
+			for (List<ViewResult.Row> partition: partitions) {
+				List<BulkDeleteDocument> answersToDelete = new ArrayList<>();
+				for (final ViewResult.Row a : partition) {
+					final BulkDeleteDocument d = new BulkDeleteDocument(a.getId(), a.getValueAsNode().get("_rev").asText());
+					answersToDelete.add(d);
+				}
+				List<DocumentOperationResult> errors = db.executeBulk(answersToDelete);
+				count += partition.size() - errors.size();
+				if (errors.size() > 0) {
+					logger.error("Could not bulk delete {} of {} answers.", errors.size(), partition.size());
+				}
+			}
+			dbLogger.log("delete", "type", "answer", "answerCount", count);
+
+			return count;
+		} catch (final DbAccessException e) {
+			logger.error("Could not delete answers for content {}.", content.getId(), e);
+		}
+
+		return 0;
+	}
+
+	@Override
+	public Answer getMyAnswer(final User me, final String questionId, final int piRound) {
+		final List<Answer> answerList = queryView("by_questionid_user_piround",
+				ComplexKey.of(questionId, me.getUsername(), piRound));
+		return answerList.isEmpty() ? null : answerList.get(0);
+	}
+
+	@Override
+	public List<Answer> getAnswers(final Content content, final int piRound) {
+		final String questionId = content.getId();
+		final ViewResult result = db.queryView(createQuery("by_questionid_piround_text_subject")
+						.group(true)
+						.startKey(ComplexKey.of(questionId, piRound))
+						.endKey(ComplexKey.of(questionId, piRound, ComplexKey.emptyObject())));
+		final int abstentionCount = getAbstentionAnswerCount(questionId);
+
+		List<Answer> answers = new ArrayList<>();
+		for (final ViewResult.Row d : result) {
+			final Answer a = new Answer();
+			a.setAnswerCount(d.getValueAsInt());
+			a.setAbstentionCount(abstentionCount);
+			a.setQuestionId(d.getKeyAsNode().get(0).asText());
+			a.setPiRound(piRound);
+			final JsonNode answerTextNode = d.getKeyAsNode().get(3);
+			a.setAnswerText(answerTextNode.isNull() ? null : answerTextNode.asText());
+			answers.add(a);
+		}
+
+		return answers;
+	}
+
+	@Override
+	public List<Answer> getAllAnswers(final Content content) {
+		final String questionId = content.getId();
+		final ViewResult result = db.queryView(createQuery("by_questionid_piround_text_subject")
+				.group(true)
+				.startKey(ComplexKey.of(questionId))
+				.endKey(ComplexKey.of(questionId, ComplexKey.emptyObject())));
+		final int abstentionCount = getAbstentionAnswerCount(questionId);
+
+		final List<Answer> answers = new ArrayList<>();
+		for (final ViewResult.Row d : result.getRows()) {
+			final Answer a = new Answer();
+			a.setAnswerCount(d.getValueAsInt());
+			a.setAbstentionCount(abstentionCount);
+			a.setQuestionId(d.getKeyAsNode().get(0).asText());
+			final JsonNode answerTextNode = d.getKeyAsNode().get(3);
+			final JsonNode answerSubjectNode = d.getKeyAsNode().get(4);
+			final boolean successfulFreeTextAnswer = d.getKeyAsNode().get(5).asBoolean();
+			a.setAnswerText(answerTextNode.isNull() ? null : answerTextNode.asText());
+			a.setAnswerSubject(answerSubjectNode.isNull() ? null : answerSubjectNode.asText());
+			a.setSuccessfulFreeTextAnswer(successfulFreeTextAnswer);
+			answers.add(a);
+		}
+
+		return answers;
+	}
+
+	@Cacheable("answers")
+	@Override
+	public List<Answer> getAnswers(final Content content) {
+		return this.getAnswers(content, content.getPiRound());
+	}
+
+	@Override
+	public int getAbstentionAnswerCount(final String questionId) {
+		final ViewResult result = db.queryView(createQuery("by_questionid_piround_text_subject")
+				//.group(true)
+				.startKey(ComplexKey.of(questionId))
+				.endKey(ComplexKey.of(questionId, ComplexKey.emptyObject())));
+
+		return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt();
+	}
+
+	@Override
+	public int getAnswerCount(final Content content, final int piRound) {
+		final ViewResult result = db.queryView(createQuery("by_questionid_piround_text_subject")
+				//.group(true)
+				.startKey(ComplexKey.of(content.getId(), piRound))
+				.endKey(ComplexKey.of(content.getId(), piRound, ComplexKey.emptyObject())));
+
+		return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt();
+	}
+
+	@Override
+	public int getTotalAnswerCountByQuestion(final Content content) {
+		final ViewResult result = db.queryView(createQuery("by_questionid_piround_text_subject")
+				//.group(true)
+				.startKey(ComplexKey.of(content.getId()))
+				.endKey(ComplexKey.of(content.getId(), ComplexKey.emptyObject())));
+
+		return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt();
+	}
+
+	@Override
+	public List<Answer> getFreetextAnswers(final String questionId, final int start, final int limit) {
+		final int qSkip = start > 0 ? start : -1;
+		final int qLimit = limit > 0 ? limit : -1;
+
+		final List<Answer> answers = db.queryView(createQuery("by_questionid_timestamp")
+						.skip(qSkip)
+						.limit(qLimit)
+						//.includeDocs(true)
+						.startKey(ComplexKey.of(questionId))
+						.endKey(ComplexKey.of(questionId, ComplexKey.emptyObject()))
+						.descending(true),
+				Answer.class);
+
+		return answers;
+	}
+
+	@Override
+	public List<Answer> getMyAnswers(final User me, final Session s) {
+		return queryView("by_user_sessionid", ComplexKey.of(me.getUsername(), s.getId()));
+	}
+
+	@Override
+	public int getTotalAnswerCount(final String sessionKey) {
+		final Session s = sessionRepository.getSessionFromKeyword(sessionKey);
+		if (s == null) {
+			throw new NotFoundException();
+		}
+		final ViewResult result = db.queryView(createQuery("by_sessionid_variant").key(s.getId()));
+
+		return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt();
+	}
+
+	@CacheEvict(value = "answers", key = "#content")
+	@Override
+	public Answer saveAnswer(final Answer answer, final User user, final Content content, final Session session) {
+		db.create(answer);
+		this.answerQueue.offer(new AnswerQueueElement(session, content, answer, user));
+
+		return answer;
+	}
+
+	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
+	@CacheEvict(value = "answers", allEntries = true)
+	@Override
+	public Answer updateAnswer(final Answer answer) {
+		try {
+			update(answer);
+			return answer;
+		} catch (final UpdateConflictException e) {
+			logger.error("Could not update answer {}.", answer, e);
+		}
+
+		return null;
+	}
+
+	/* TODO: Only evict cache entry for the answer's session. This requires some refactoring. */
+	@CacheEvict(value = "answers", allEntries = true)
+	@Override
+	public void deleteAnswer(final String answerId) {
+		try {
+			/* TODO: use id and rev instead of loading the answer */
+			db.delete(get(answerId));
+			dbLogger.log("delete", "type", "answer");
+		} catch (final DbAccessException e) {
+			logger.error("Could not delete answer {}.", answerId, e);
+		}
+	}
+
+	@Override
+	public int countLectureQuestionAnswers(final Session session) {
+		return countQuestionVariantAnswers(session, "lecture");
+	}
+
+	@Override
+	public int countPreparationQuestionAnswers(final Session session) {
+		return countQuestionVariantAnswers(session, "preparation");
+	}
+
+	private int countQuestionVariantAnswers(final Session session, final String variant) {
+		final ViewResult result = db.queryView(createQuery("by_sessionid_variant")
+				.key(ComplexKey.of(session.getId(), variant)));
+
+		return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt();
+	}
+
+	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
+	@CacheEvict(value = "answers", allEntries = true)
+	@Override
+	public int deleteAllQuestionsAnswers(final Session session) {
+		final List<Content> contents = contentRepository.getQuestions(session.getId());
+		contentRepository.resetQuestionsRoundState(session, contents);
+
+		return deleteAllAnswersForQuestions(contents);
+	}
+
+	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
+	@CacheEvict(value = "answers", allEntries = true)
+	@Override
+	public int deleteAllPreparationAnswers(final Session session) {
+		final List<Content> contents = contentRepository.getQuestions(session.getId(), "preparation");
+		contentRepository.resetQuestionsRoundState(session, contents);
+
+		return deleteAllAnswersForQuestions(contents);
+	}
+
+	/* TODO: Only evict cache entry for the answer's question. This requires some refactoring. */
+	@CacheEvict(value = "answers", allEntries = true)
+	@Override
+	public int deleteAllLectureAnswers(final Session session) {
+		final List<Content> contents = contentRepository.getQuestions(session.getId(), "lecture");
+		contentRepository.resetQuestionsRoundState(session, contents);
+
+		return deleteAllAnswersForQuestions(contents);
+	}
+
+	public int deleteAllAnswersForQuestions(List<Content> contents) {
+		List<String> questionIds = new ArrayList<>();
+		for (Content q : contents) {
+			questionIds.add(q.getId());
+		}
+		final ViewResult result = db.queryView(createQuery("by_questionid")
+				.keys(questionIds));
+		final List<BulkDeleteDocument> allAnswers = new ArrayList<>();
+		for (ViewResult.Row a : result.getRows()) {
+			final BulkDeleteDocument d = new BulkDeleteDocument(a.getId(), a.getValueAsNode().get("_rev").asText());
+			allAnswers.add(d);
+		}
+		try {
+			List<DocumentOperationResult> errors = db.executeBulk(allAnswers);
+
+			return allAnswers.size() - errors.size();
+		} catch (DbAccessException e) {
+			logger.error("Could not bulk delete answers.", e);
+		}
+
+		return 0;
+	}
+
+	public int[] deleteAllAnswersWithQuestions(List<Content> contents) {
+		List<String> questionIds = new ArrayList<>();
+		final List<BulkDeleteDocument> allQuestions = new ArrayList<>();
+		for (Content q : contents) {
+			final BulkDeleteDocument d = new BulkDeleteDocument(q.getId(), q.getRevision());
+			questionIds.add(q.getId());
+			allQuestions.add(d);
+		}
+
+		final ViewResult result = db.queryView(createQuery("by_questionid")
+				.key(questionIds));
+		final List<BulkDeleteDocument> allAnswers = new ArrayList<>();
+		for (ViewResult.Row a : result.getRows()) {
+			final BulkDeleteDocument d = new BulkDeleteDocument(a.getId(), a.getValueAsNode().get("_rev").asText());
+			allAnswers.add(d);
+		}
+
+		try {
+			List<BulkDeleteDocument> deleteList = new ArrayList<>(allAnswers);
+			deleteList.addAll(allQuestions);
+			List<DocumentOperationResult> errors = db.executeBulk(deleteList);
+
+			/* TODO: subtract errors from count */
+			return new int[] {allQuestions.size(), allAnswers.size()};
+		} catch (DbAccessException e) {
+			logger.error("Could not bulk delete contents and answers.", e);
+		}
+
+		return new int[] {0, 0};
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbContentRepository.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbContentRepository.java
index ba83397e9d4426d4c60c0e828cdfb050dfda1faf..1e91fb34eb68dff249749afbdc38ec0e405eff10 100644
--- a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbContentRepository.java
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbContentRepository.java
@@ -1,9 +1,9 @@
 package de.thm.arsnova.persistance.couchdb;
 
-import de.thm.arsnova.dao.IDatabaseDao;
 import de.thm.arsnova.entities.Content;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
+import de.thm.arsnova.persistance.AnswerRepository;
 import de.thm.arsnova.persistance.ContentRepository;
 import de.thm.arsnova.persistance.LogEntryRepository;
 import org.ektorp.ComplexKey;
@@ -37,7 +37,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 	private LogEntryRepository dbLogger;
 
 	@Autowired
-	private IDatabaseDao databaseDao;
+	private AnswerRepository answerRepository;
 
 	public CouchDbContentRepository(Class<Content> type, CouchDbConnector db, boolean createIfNotExists) {
 		super(type, db, createIfNotExists);
@@ -145,7 +145,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 	@Override
 	public int deleteQuestionWithAnswers(final Content content) {
 		try {
-			int count = databaseDao.deleteAnswers(content);
+			int count = answerRepository.deleteAnswers(content);
 			db.delete(content);
 			dbLogger.log("delete", "type", "content", "answerCount", count);
 
@@ -181,7 +181,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 			contents.add(q);
 		}
 
-		int[] count = databaseDao.deleteAllAnswersWithQuestions(contents);
+		int[] count = answerRepository.deleteAllAnswersWithQuestions(contents);
 		dbLogger.log("delete", "type", "question", "questionCount", count[0]);
 		dbLogger.log("delete", "type", "answer", "answerCount", count[1]);
 
@@ -191,7 +191,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 	@Override
 	public List<String> getUnAnsweredQuestionIds(final Session session, final User user) {
 		final ViewResult result = db.queryView(createQuery("questionid_by_user_sessionid_variant")
-				.designDocId("_design/answer")
+				.designDocId("_design/Answer")
 				.startKey(ComplexKey.of(user.getUsername(), session.getId()))
 				.endKey(ComplexKey.of(user.getUsername(), session.getId(), ComplexKey.emptyObject())));
 		List<String> answeredIds = new ArrayList<>();
@@ -204,7 +204,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 	@Override
 	public List<String> getUnAnsweredLectureQuestionIds(final Session session, final User user) {
 		final ViewResult result = db.queryView(createQuery("questionid_piround_by_user_sessionid_variant")
-				.designDocId("_design/answer")
+				.designDocId("_design/Answer")
 				.key(ComplexKey.of(user.getUsername(), session.getId(), "lecture")));
 		Map<String, Integer> answeredQuestions = new HashMap<>();
 		for (ViewResult.Row row : result.getRows()) {
@@ -217,7 +217,7 @@ public class CouchDbContentRepository extends CouchDbRepositorySupport<Content>
 	@Override
 	public List<String> getUnAnsweredPreparationQuestionIds(final Session session, final User user) {
 		final ViewResult result = db.queryView(createQuery("questionid_piround_by_user_sessionid_variant")
-				.designDocId("_design/answer")
+				.designDocId("_design/Answer")
 				.key(ComplexKey.of(user.getUsername(), session.getId(), "preparation")));
 		Map<String, Integer> answeredQuestions = new HashMap<>();
 		for (ViewResult.Row row : result.getRows()) {
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbSessionRepository.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbSessionRepository.java
index 0d0da5868042151d096c7c8242b7661560eca471..ab0166b23e1830fc4d53ea9bcabf5d5804e6e3db 100644
--- a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbSessionRepository.java
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbSessionRepository.java
@@ -504,11 +504,10 @@ public class CouchDbSessionRepository extends CouchDbRepositorySupport<Session>
 	}
 
 	private List<SessionInfo> getInfosForSessions(final List<Session> sessions) {
-		/* TODO: migrate to new view */
 		List<String> sessionIds = sessions.stream().map(Session::getId).collect(Collectors.toList());
 		final ViewQuery questionCountView = createQuery("by_sessionid").designDocId("_design/Content")
 				.group(true).keys(sessionIds);
-		final ViewQuery answerCountView = createQuery("by_sessionid").designDocId("_design/answer")
+		final ViewQuery answerCountView = createQuery("by_sessionid").designDocId("_design/Answer")
 				.group(true).keys(sessionIds);
 		final ViewQuery commentCountView = createQuery("by_sessionid").designDocId("_design/Comment")
 				.group(true).keys(sessionIds);
@@ -519,7 +518,7 @@ public class CouchDbSessionRepository extends CouchDbRepositorySupport<Session>
 	}
 
 	private List<SessionInfo> getInfosForVisitedSessions(final List<Session> sessions, final User user) {
-		final ViewQuery answeredQuestionsView = createQuery("by_user_sessionid").designDocId("_design/answer")
+		final ViewQuery answeredQuestionsView = createQuery("by_user_sessionid").designDocId("_design/Answer")
 				.keys(sessions.stream().map(session -> ComplexKey.of(user.getUsername(), session.getId())).collect(Collectors.toList()));
 		final ViewQuery questionIdsView = createQuery("by_sessionid").designDocId("_design/Content")
 				.keys(sessions.stream().map(Session::getId).collect(Collectors.toList()));
diff --git a/src/main/java/de/thm/arsnova/services/ContentService.java b/src/main/java/de/thm/arsnova/services/ContentService.java
index c08d1ccbf8e3837132e5b536abeb5ff23139cb96..0cf430d1e755f76d38eb429aaaf06afdf0c1d893 100644
--- a/src/main/java/de/thm/arsnova/services/ContentService.java
+++ b/src/main/java/de/thm/arsnova/services/ContentService.java
@@ -30,6 +30,7 @@ import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.ForbiddenException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
+import de.thm.arsnova.persistance.AnswerRepository;
 import de.thm.arsnova.persistance.CommentRepository;
 import de.thm.arsnova.persistance.ContentRepository;
 import de.thm.arsnova.persistance.SessionRepository;
@@ -71,6 +72,9 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	@Autowired
 	private ContentRepository contentRepository;
 
+	@Autowired
+	private AnswerRepository answerRepository;
+
 	@Autowired
 	private ImageUtils imageUtils;
 
@@ -285,7 +289,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		}
 
 		content.resetRoundManagementState();
-		databaseDao.deleteAnswers(content);
+		answerRepository.deleteAnswers(content);
 		update(content);
 		this.publisher.publishEvent(new PiRoundResetEvent(this, session, content));
 	}
@@ -392,7 +396,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		final Content content = contentRepository.getQuestion(questionId);
 		content.resetQuestionState();
 		contentRepository.updateQuestion(content);
-		databaseDao.deleteAnswers(content);
+		answerRepository.deleteAnswers(content);
 	}
 
 	@Override
@@ -418,12 +422,12 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if (content == null) {
 			throw new NotFoundException();
 		}
-		return databaseDao.getMyAnswer(userService.getCurrentUser(), questionId, content.getPiRound());
+		return answerRepository.getMyAnswer(userService.getCurrentUser(), questionId, content.getPiRound());
 	}
 
 	@Override
 	public void readFreetextAnswer(final String answerId, final User user) {
-		final Answer answer = databaseDao.getObjectFromId(answerId, Answer.class);
+		final Answer answer = answerRepository.get(answerId);
 		if (answer == null) {
 			throw new NotFoundException();
 		}
@@ -433,7 +437,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		final Session session = sessionRepository.getSessionFromId(answer.getSessionId());
 		if (session.isCreator(user)) {
 			answer.setRead(true);
-			databaseDao.updateAnswer(answer);
+			answerRepository.updateAnswer(answer);
 		}
 	}
 
@@ -446,7 +450,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		}
 		return "freetext".equals(content.getQuestionType())
 				? getFreetextAnswers(questionId, offset, limit)
-						: databaseDao.getAnswers(content, piRound);
+						: answerRepository.getAnswers(content, piRound);
 	}
 
 	@Override
@@ -459,7 +463,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if ("freetext".equals(content.getQuestionType())) {
 			return getFreetextAnswers(questionId, offset, limit);
 		} else {
-			return databaseDao.getAnswers(content);
+			return answerRepository.getAnswers(content);
 		}
 	}
 
@@ -473,7 +477,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if ("freetext".equals(content.getQuestionType())) {
 			return getFreetextAnswers(questionId, offset, limit);
 		} else {
-			return databaseDao.getAllAnswers(content);
+			return answerRepository.getAllAnswers(content);
 		}
 	}
 
@@ -486,9 +490,9 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		}
 
 		if ("freetext".equals(content.getQuestionType())) {
-			return databaseDao.getTotalAnswerCountByQuestion(content);
+			return answerRepository.getTotalAnswerCountByQuestion(content);
 		} else {
-			return databaseDao.getAnswerCount(content, content.getPiRound());
+			return answerRepository.getAnswerCount(content, content.getPiRound());
 		}
 	}
 
@@ -500,7 +504,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 			return 0;
 		}
 
-		return databaseDao.getAnswerCount(content, piRound);
+		return answerRepository.getAnswerCount(content, piRound);
 	}
 
 	@Override
@@ -511,7 +515,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 			return 0;
 		}
 
-		return databaseDao.getAbstentionAnswerCount(questionId);
+		return answerRepository.getAbstentionAnswerCount(questionId);
 	}
 
 	@Override
@@ -522,13 +526,13 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 			return 0;
 		}
 
-		return databaseDao.getTotalAnswerCountByQuestion(content);
+		return answerRepository.getTotalAnswerCountByQuestion(content);
 	}
 
 	@Override
 	@PreAuthorize("isAuthenticated()")
 	public List<Answer> getFreetextAnswers(final String questionId, final int offset, final int limit) {
-		final List<Answer> answers = databaseDao.getFreetextAnswers(questionId, offset, limit);
+		final List<Answer> answers = answerRepository.getFreetextAnswers(questionId, offset, limit);
 		if (answers == null) {
 			throw new NotFoundException();
 		}
@@ -552,7 +556,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		}
 
 		/* filter answers by active piRound per question */
-		final List<Answer> answers = databaseDao.getMyAnswers(userService.getCurrentUser(), session);
+		final List<Answer> answers = answerRepository.getMyAnswers(userService.getCurrentUser(), session);
 		final List<Answer> filteredAnswers = new ArrayList<>();
 		for (final Answer answer : answers) {
 			final Content content = questionIdToQuestion.get(answer.getQuestionId());
@@ -577,7 +581,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	@Override
 	@PreAuthorize("isAuthenticated()")
 	public int getTotalAnswerCount(final String sessionKey) {
-		return databaseDao.getTotalAnswerCount(sessionKey);
+		return answerRepository.getTotalAnswerCount(sessionKey);
 	}
 
 	@Override
@@ -690,8 +694,12 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if (content == null) {
 			throw new NotFoundException();
 		}
+		final Session session = sessionRepository.getSessionFromId(content.getSessionId());
 
 		Answer theAnswer = answer.generateAnswerEntity(user, content);
+		theAnswer.setUser(user.getUsername());
+		theAnswer.setQuestionId(content.getId());
+		theAnswer.setSessionId(session.getId());
 		if ("freetext".equals(content.getQuestionType())) {
 			imageUtils.generateThumbnailImage(theAnswer);
 			if (content.isFixedAnswer() && content.getText() != null) {
@@ -705,7 +713,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 			}
 		}
 
-		return databaseDao.saveAnswer(theAnswer, user, content, sessionRepository.getSessionFromId(content.getSessionId()));
+		return answerRepository.saveAnswer(theAnswer, user, content, session);
 	}
 
 	@Override
@@ -722,8 +730,11 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 			imageUtils.generateThumbnailImage(realAnswer);
 			content.checkTextStrictOptions(realAnswer);
 		}
-		final Answer result = databaseDao.updateAnswer(realAnswer);
 		final Session session = sessionRepository.getSessionFromId(content.getSessionId());
+		answer.setUser(user.getUsername());
+		answer.setQuestionId(content.getId());
+		answer.setSessionId(session.getId());
+		final Answer result = answerRepository.updateAnswer(realAnswer);
 		this.publisher.publishEvent(new NewAnswerEvent(this, session, result, user, content));
 
 		return result;
@@ -741,7 +752,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if (user == null || session == null || !session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
-		databaseDao.deleteAnswer(answerId);
+		answerRepository.deleteAnswer(answerId);
 
 		this.publisher.publishEvent(new DeleteAnswerEvent(this, session, content));
 	}
@@ -832,7 +843,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	 */
 	@Override
 	public int countLectureQuestionAnswersInternal(final String sessionkey) {
-		return databaseDao.countLectureQuestionAnswers(getSession(sessionkey));
+		return answerRepository.countLectureQuestionAnswers(getSession(sessionkey));
 	}
 
 	@Override
@@ -845,8 +856,8 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		}
 
 		map.put("_id", questionId);
-		map.put("answers", databaseDao.getAnswerCount(content, content.getPiRound()));
-		map.put("abstentions", databaseDao.getAbstentionAnswerCount(questionId));
+		map.put("answers", answerRepository.getAnswerCount(content, content.getPiRound()));
+		map.put("abstentions", answerRepository.getAbstentionAnswerCount(questionId));
 
 		return map;
 	}
@@ -863,7 +874,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	 */
 	@Override
 	public int countPreparationQuestionAnswersInternal(final String sessionkey) {
-		return databaseDao.countPreparationQuestionAnswers(getSession(sessionkey));
+		return answerRepository.countPreparationQuestionAnswers(getSession(sessionkey));
 	}
 
 	/*
@@ -966,7 +977,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		if (!session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
-		databaseDao.deleteAllQuestionsAnswers(session);
+		answerRepository.deleteAllQuestionsAnswers(session);
 
 		this.publisher.publishEvent(new DeleteAllQuestionsAnswersEvent(this, session));
 	}
@@ -975,7 +986,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
 	public void deleteAllPreparationAnswers(String sessionkey) {
 		final Session session = getSession(sessionkey);
-		databaseDao.deleteAllPreparationAnswers(session);
+		answerRepository.deleteAllPreparationAnswers(session);
 
 		this.publisher.publishEvent(new DeleteAllPreparationAnswersEvent(this, session));
 	}
@@ -984,7 +995,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
 	public void deleteAllLectureAnswers(String sessionkey) {
 		final Session session = getSession(sessionkey);
-		databaseDao.deleteAllLectureAnswers(session);
+		answerRepository.deleteAllLectureAnswers(session);
 
 		this.publisher.publishEvent(new DeleteAllLectureAnswersEvent(this, session));
 	}
@@ -1000,7 +1011,7 @@ public class ContentService implements IContentService, ApplicationEventPublishe
 		Answer answer = null;
 
 		for (Answer a : answers) {
-			if (answerId.equals(a.get_id())) {
+			if (answerId.equals(a.getId())) {
 				answer = a;
 				break;
 			}
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index 6dc8bb931103247839034b0284de259a87f05e75..099e1dfd19216f2957049e47f184bc57d292d515 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -96,118 +96,18 @@ public class StubDatabaseDao implements IDatabaseDao {
 		stubQuestions.put("12345678", contents);
 	}
 
-	@Override
-	public Answer getMyAnswer(User user, String questionId, int piRound) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public int getAnswerCount(Content content, int piRound) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public List<Answer> getFreetextAnswers(String questionId, final int start, final int limit) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Answer> getMyAnswers(User user, Session session) {
-		return new ArrayList<>();
-	}
-
-	@Override
-	public int getTotalAnswerCount(String sessionKey) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int deleteAnswers(Content content) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public Answer updateAnswer(Answer answer) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public void deleteAnswer(String answerId) {
-		// TODO Auto-generated method stub
-	}
-
 	@Override
 	public int deleteInactiveGuestVisitedSessionLists(long lastActivityBefore) {
 		// TODO Auto-generated method stub
 		return 0;
 	}
 
-	@Override
-	public int countLectureQuestionAnswers(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int countPreparationQuestionAnswers(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int deleteAllQuestionsAnswers(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
 	@Override
 	public CourseScore getLearningProgress(Session session) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
-	@Override
-	public int deleteAllPreparationAnswers(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int deleteAllLectureAnswers(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int getAbstentionAnswerCount(String questionId) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public List<Answer> getAnswers(Content content, int piRound) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public List<Answer> getAnswers(Content content) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Answer saveAnswer(Answer answer, User user, Content content, Session session) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
 	@Override
 	public Statistics getStatistics() {
 		final Statistics stats = new Statistics();
@@ -219,18 +119,6 @@ public class StubDatabaseDao implements IDatabaseDao {
 		return stats;
 	}
 
-	@Override
-	public List<Answer> getAllAnswers(Content content) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public int getTotalAnswerCountByQuestion(Content content) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
 	@Override
 	public <T> T getObjectFromId(String documentId, Class<T> klass) {
 		// TODO Auto-generated method stub
@@ -248,10 +136,4 @@ public class StubDatabaseDao implements IDatabaseDao {
 		// TODO Auto-generated method stub
 		return null;
 	}
-
-	@Override
-	public int[] deleteAllAnswersWithQuestions(List<Content> contents) {
-		// TODO Auto-generated method stub
-		return new int[0];
-	}
 }