diff --git a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
index 194822867c9ed71650d7d63f0e50de47bfa4b4c0..003bb2d0d297348ab20d07dc1b7004da3db9b1bb 100644
--- a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
@@ -24,6 +24,7 @@ import de.thm.arsnova.event.AfterCreationEvent;
 import de.thm.arsnova.event.AfterDeletionEvent;
 import de.thm.arsnova.event.AfterFullUpdateEvent;
 import de.thm.arsnova.event.AfterPatchEvent;
+import de.thm.arsnova.event.AfterUpdateEvent;
 import de.thm.arsnova.event.BeforeCreationEvent;
 import de.thm.arsnova.event.BeforeDeletionEvent;
 import de.thm.arsnova.event.BeforeFullUpdateEvent;
@@ -31,10 +32,16 @@ import de.thm.arsnova.event.BeforePatchEvent;
 import de.thm.arsnova.model.Entity;
 import de.thm.arsnova.model.serialization.View;
 import de.thm.arsnova.persistence.CrudRepository;
+
+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.event.EventListener;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.access.prepost.PreFilter;
+import org.springframework.stereotype.Component;
 
 import java.io.IOException;
 import java.util.Date;
@@ -63,17 +70,16 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 	@Override
 	@PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')")
 	public T get(final String id) {
-		return repository.findOne(id);
+		return get(id, false);
 	}
 
 	@Override
+	@Cacheable(cacheNames = "entity", key = "#root.target.getTypeName() + '-' + #id", condition = "#internal == false")
 	public T get(final String id, final boolean internal) {
 		T entity;
+		entity = repository.findOne(id);
 		if (internal) {
-			entity = repository.findOne(id);
 			entity.setInternal(true);
-		} else {
-			entity = get(id);
 		}
 		modifyRetrieved(entity);
 
@@ -260,4 +266,25 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 	public void setApplicationEventPublisher(final ApplicationEventPublisher applicationEventPublisher) {
 		this.eventPublisher = applicationEventPublisher;
 	}
+
+	@Component
+	public static class EntityCacheHandler {
+		@CachePut(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
+		@EventListener
+		public Entity handleCreate(AfterCreationEvent event) {
+			return event.getEntity();
+		}
+
+		@CachePut(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
+		@EventListener
+		public Entity handleUpdate(AfterUpdateEvent event) {
+			return event.getEntity();
+		}
+
+		@CacheEvict(cacheNames = "entity", key = "#event.entity.class.simpleName.toLowerCase() + '-' + #event.entity.id")
+		@EventListener
+		public void handleDelete(AfterDeletionEvent event) {
+
+		}
+	}
 }
diff --git a/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java b/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
index eed130c37c8516cc027fb9b82eddbbc9b42f1044..ac97ac25c1b6ccdd3c614543b4938b0ad65ee71c 100644
--- a/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
+++ b/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
@@ -12,6 +12,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.cache.CacheManager;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 import org.springframework.test.context.ActiveProfiles;
@@ -24,8 +25,9 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 import static org.mockito.AdditionalAnswers.returnsFirstArg;
 import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Mockito.any;
@@ -44,6 +46,9 @@ public class DefaultEntityServiceImplTest {
 	@Autowired
 	private ApplicationEventPublisher eventPublisher;
 
+	@Autowired
+	private CacheManager cacheManager;
+
 	@Autowired
 	private RoomRepository roomRepository;
 
@@ -130,4 +135,40 @@ public class DefaultEntityServiceImplTest {
 		assertEquals(patchedClosed, room2.isClosed());
 		assertEquals(originalOwnerId2, room2.getOwnerId());
 	}
+
+	@Test
+	@WithMockUser("TestUser")
+	public void testCaching() {
+		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
+		final DefaultEntityServiceImpl<Room> entityService = new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper);
+		entityService.setApplicationEventPublisher(eventPublisher);
+
+		final Room room1 = new Room();
+		room1.setId("a34876427c634a9b9cb56789d73607f0");
+		room1.setOwnerId("TestUser");
+		final Room room2 = new Room();
+		room2.setId("4638748d89884ff7936d7fe994a4090c");
+		room2.setOwnerId("TestUser");
+		final Room room3 = new Room();
+		room3.setId("c9651db0a67b49789a354e90e0401032");
+		room3.setOwnerId("TestUser");
+		final Room room4 = new Room();
+		room4.setId("66c1673056b2410b87335b9f317da5aa");
+		room4.setOwnerId("TestUser");
+
+		when(roomRepository.findById(any(String.class))).thenReturn(Optional.of(room1));
+		when(roomRepository.findOne(any(String.class))).thenReturn(room1);
+		assertSame(room1, entityService.get(room1.getId()));
+		/* room1 should now be cached for room1.id */
+		assertSame(room1, cacheManager.getCache("entity").get("room-" + room1.getId()).get());
+		when(roomRepository.findById(any(String.class))).thenReturn(Optional.of(room2));
+		when(roomRepository.findOne(any(String.class))).thenReturn(room2);
+		assertSame(room1, entityService.get(room1.getId()));
+		assertSame("Cache should not be used if internal == true.", room2, entityService.get(room1.getId(), true));
+
+		entityService.delete(room1);
+		/* room1 should no longer be cached for room1.id */
+		assertSame("Entity should not be cached.", null, cacheManager.getCache("entity").get("room-" + room1.getId()));
+		assertSame(room2, entityService.get(room1.getId()));
+	}
 }