diff --git a/pom.xml b/pom.xml
index ce2bb3a89ee2ae3d643e5057aef220b7ed3c9210..1155820d8d3dbcc7244bbb6756078ae27767153b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -213,6 +213,19 @@
 			<groupId>org.springframework.security</groupId>
 			<artifactId>spring-security-ldap</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>org.hibernate.validator</groupId>
+			<artifactId>hibernate-validator</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate.validator</groupId>
+			<artifactId>hibernate-validator-annotation-processor</artifactId>
+		</dependency>
+		<!-- A javax.el (Unified Expression Language) implementation is needed for bean validation. -->
+		<dependency>
+			<groupId>org.mortbay.jasper</groupId>
+			<artifactId>apache-el</artifactId>
+		</dependency>
 		<dependency>
 			<groupId>com.google.guava</groupId>
 			<artifactId>guava</artifactId>
diff --git a/src/main/java/de/thm/arsnova/controller/ControllerExceptionHandler.java b/src/main/java/de/thm/arsnova/controller/ControllerExceptionHandler.java
index 0df8cd7805a533886e302ce10ae096fc908479a4..5e795ff41847a7c7f112513cdd253e213d2351d9 100644
--- a/src/main/java/de/thm/arsnova/controller/ControllerExceptionHandler.java
+++ b/src/main/java/de/thm/arsnova/controller/ControllerExceptionHandler.java
@@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.context.request.WebRequest;
 import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
 
+import de.thm.arsnova.model.EntityValidationException;
 import de.thm.arsnova.web.exceptions.BadRequestException;
 import de.thm.arsnova.web.exceptions.ForbiddenException;
 import de.thm.arsnova.web.exceptions.NoContentException;
@@ -120,6 +121,14 @@ public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
 		return helper.handleException(e, Level.DEBUG);
 	}
 
+	@ExceptionHandler(EntityValidationException.class)
+	@ResponseBody
+	@ResponseStatus(HttpStatus.BAD_REQUEST)
+	public Map<String, Object> handleEntityValidationException(
+			final EntityValidationException e, final HttpServletRequest request) {
+		return helper.handleException(e, Level.DEBUG);
+	}
+
 	@ExceptionHandler(PreconditionFailedException.class)
 	@ResponseBody
 	@ResponseStatus(HttpStatus.PRECONDITION_FAILED)
diff --git a/src/main/java/de/thm/arsnova/model/Answer.java b/src/main/java/de/thm/arsnova/model/Answer.java
index 755054ce0740ada0feec2e88830c15f22b88860b..a6e26ecca2b70e87f3a72aae376e5cb288dd76f0 100644
--- a/src/main/java/de/thm/arsnova/model/Answer.java
+++ b/src/main/java/de/thm/arsnova/model/Answer.java
@@ -23,6 +23,9 @@ import com.fasterxml.jackson.annotation.JsonView;
 import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
 import java.util.Map;
 import java.util.Objects;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.FormatAnswerTypeIdResolver;
@@ -36,11 +39,21 @@ import de.thm.arsnova.model.serialization.View;
 )
 @JsonTypeIdResolver(FormatAnswerTypeIdResolver.class)
 public class Answer extends Entity {
+	@NotEmpty
 	private String contentId;
+
+	@NotEmpty
 	private String roomId;
+
+	@NotEmpty
 	private String creatorId;
+
+	@NotNull
 	private Content.Format format;
+
+	@Positive
 	private int round;
+
 	private Map<String, Map<String, ?>> extensions;
 
 	@JsonView({View.Persistence.class, View.Public.class})
diff --git a/src/main/java/de/thm/arsnova/model/ChoiceAnswer.java b/src/main/java/de/thm/arsnova/model/ChoiceAnswer.java
index 25fb49606c448175b236e8eb2d2af946d05beb85..1c1d21e8aeaae85467e1dde72198775f391f5d28 100644
--- a/src/main/java/de/thm/arsnova/model/ChoiceAnswer.java
+++ b/src/main/java/de/thm/arsnova/model/ChoiceAnswer.java
@@ -20,12 +20,13 @@ package de.thm.arsnova.model;
 
 import com.fasterxml.jackson.annotation.JsonView;
 import java.util.List;
+import javax.validation.constraints.PositiveOrZero;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
 
 public class ChoiceAnswer extends Answer {
-	private List<Integer> selectedChoiceIndexes;
+	private List<@PositiveOrZero Integer> selectedChoiceIndexes;
 
 	@JsonView({View.Persistence.class, View.Public.class})
 	public List<Integer> getSelectedChoiceIndexes() {
diff --git a/src/main/java/de/thm/arsnova/model/ChoiceQuestionContent.java b/src/main/java/de/thm/arsnova/model/ChoiceQuestionContent.java
index 39fd66f894d27c0aefb0c9bebf70c3177941fbe1..868d1c896129b662c4e99d40060e56095c62ee33 100644
--- a/src/main/java/de/thm/arsnova/model/ChoiceQuestionContent.java
+++ b/src/main/java/de/thm/arsnova/model/ChoiceQuestionContent.java
@@ -22,13 +22,16 @@ import com.fasterxml.jackson.annotation.JsonView;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import javax.validation.constraints.NotBlank;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
 
 public class ChoiceQuestionContent extends Content {
 	public static class AnswerOption {
+		@NotBlank
 		private String label;
+
 		private int points;
 
 		@JsonView({View.Persistence.class, View.Public.class})
diff --git a/src/main/java/de/thm/arsnova/model/Comment.java b/src/main/java/de/thm/arsnova/model/Comment.java
index 4ae7708afc25c8ff3f7fc290f2242dec5201a0e7..c116f4e7239535fca0a74d1f8cf9a42cfd554d71 100644
--- a/src/main/java/de/thm/arsnova/model/Comment.java
+++ b/src/main/java/de/thm/arsnova/model/Comment.java
@@ -22,16 +22,30 @@ import com.fasterxml.jackson.annotation.JsonView;
 import java.util.Date;
 import java.util.Map;
 import java.util.Objects;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
 
 public class Comment extends Entity {
+	@NotEmpty
 	private String roomId;
+
+	@NotEmpty
 	private String creatorId;
+
+	@NotBlank
 	private String subject;
+
+	@NotBlank
 	private String body;
+
+	@NotNull
 	private Date timestamp;
+
 	private boolean read;
 	private Map<String, Map<String, ?>> extensions;
 
diff --git a/src/main/java/de/thm/arsnova/model/Content.java b/src/main/java/de/thm/arsnova/model/Content.java
index d0e45af149272d30d4920c7c6381db280005ec54..b23e416152202d9cf0da63a583e11b2d7081844c 100644
--- a/src/main/java/de/thm/arsnova/model/Content.java
+++ b/src/main/java/de/thm/arsnova/model/Content.java
@@ -26,6 +26,10 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.FormatContentTypeIdResolver;
@@ -49,7 +53,9 @@ public class Content extends Entity {
 	}
 
 	public static class State {
+		@Positive
 		private int round = 1;
+
 		private Date roundEndTimestamp;
 		private boolean visible = true;
 		private boolean solutionVisible = false;
@@ -152,10 +158,18 @@ public class Content extends Entity {
 		}
 	}
 
+	@NotEmpty
 	private String roomId;
+
+	@NotBlank
 	private String subject;
+
+	@NotBlank
 	private String body;
+
+	@NotNull
 	private Format format;
+
 	private Set<String> groups;
 	private boolean abstentionsAllowed;
 	private State state;
diff --git a/src/main/java/de/thm/arsnova/model/EntityValidationException.java b/src/main/java/de/thm/arsnova/model/EntityValidationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..15eab9507ad80df31be595ead3dafec4812c577a
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/model/EntityValidationException.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2019 The ARSnova Team and Contributors
+ *
+ * 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.model;
+
+import javax.validation.ValidationException;
+import org.springframework.validation.Errors;
+
+public class EntityValidationException extends ValidationException {
+	private Errors errors;
+	private Entity entity;
+
+	public EntityValidationException(final Errors errors, final Entity entity) {
+		super(errors.getAllErrors().toString());
+		this.errors = errors;
+		this.entity = entity;
+	}
+
+	public Errors getErrors() {
+		return errors;
+	}
+
+	public Entity getEntity() {
+		return entity;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/model/Motd.java b/src/main/java/de/thm/arsnova/model/Motd.java
index 30f1f6c7b1786e76026e1b14db95415e6acf4f43..08ba9bd7f53df9acacdec00da6c07604120c4e57 100644
--- a/src/main/java/de/thm/arsnova/model/Motd.java
+++ b/src/main/java/de/thm/arsnova/model/Motd.java
@@ -21,6 +21,9 @@ package de.thm.arsnova.model;
 import com.fasterxml.jackson.annotation.JsonView;
 import java.util.Date;
 import java.util.Objects;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
@@ -34,11 +37,19 @@ public class Motd extends Entity {
 		ROOM
 	}
 
+	@NotEmpty
 	private String roomId;
+
 	private Date startDate;
 	private Date endDate;
+
+	@NotBlank
 	private String title;
+
+	@NotBlank
 	private String body;
+
+	@NotNull
 	private Audience audience;
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/model/Room.java b/src/main/java/de/thm/arsnova/model/Room.java
index 00145bd286959b60040f4d6bb2d026d0653357dd..689eae0a866629bf4ae1dc3fef4a2ee7373baaa3 100644
--- a/src/main/java/de/thm/arsnova/model/Room.java
+++ b/src/main/java/de/thm/arsnova/model/Room.java
@@ -25,13 +25,17 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
 
 public class Room extends Entity {
 	public static class ContentGroup {
+		@NotBlank
 		private String name;
+
 		private Set<String> contentIds;
 		private boolean autoSort;
 
@@ -105,7 +109,9 @@ public class Room extends Entity {
 			EXECUTIVE_MODERATOR
 		}
 
+		@NotEmpty
 		private String userId;
+
 		private Set<Role> roles;
 
 		@JsonView({View.Persistence.class, View.Public.class})
@@ -448,10 +454,18 @@ public class Room extends Entity {
 		}
 	}
 
+	@NotEmpty
 	private String shortId;
+
+	@NotEmpty
 	private String ownerId;
+
+	@NotBlank
 	private String name;
+
+	@NotBlank
 	private String abbreviation;
+
 	private String description;
 	private boolean closed;
 	private Set<ContentGroup> contentGroups;
diff --git a/src/main/java/de/thm/arsnova/model/TextAnswer.java b/src/main/java/de/thm/arsnova/model/TextAnswer.java
index f4a2069970bc705e162eb403c481423d1f873a06..d6ed249e507153a412990861973034ab3ef340d3 100644
--- a/src/main/java/de/thm/arsnova/model/TextAnswer.java
+++ b/src/main/java/de/thm/arsnova/model/TextAnswer.java
@@ -20,13 +20,19 @@ package de.thm.arsnova.model;
 
 import com.fasterxml.jackson.annotation.JsonView;
 import java.util.Date;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
 
 public class TextAnswer extends Answer {
+	@NotBlank
 	private String subject;
+
+	@NotBlank
 	private String body;
+
 	private boolean read;
 
 	@JsonView({View.Persistence.class, View.Public.class})
diff --git a/src/main/java/de/thm/arsnova/model/UserProfile.java b/src/main/java/de/thm/arsnova/model/UserProfile.java
index 80b18b5dd38af86ef4bb239945c2b18b6d973735..314b3dc6f676130d00fce3443af211d7c712500f 100644
--- a/src/main/java/de/thm/arsnova/model/UserProfile.java
+++ b/src/main/java/de/thm/arsnova/model/UserProfile.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import javax.validation.constraints.NotEmpty;
 import org.springframework.core.style.ToStringCreator;
 
 import de.thm.arsnova.model.serialization.View;
@@ -43,7 +44,9 @@ public class UserProfile extends Entity {
 	}
 
 	public static class Account {
+		@NotEmpty
 		private String password;
+
 		private String activationKey;
 		private String passwordResetKey;
 		private Date passwordResetTime;
diff --git a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java
index 465779fc0d9e08ec243a8bf0e4e411dab2ad18f2..c231d311bdf22350cb8e2849427805bedc4b0cbd 100644
--- a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java
@@ -35,6 +35,7 @@ import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.event.AfterCreationEvent;
 import de.thm.arsnova.event.BeforeCreationEvent;
@@ -69,8 +70,9 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen
 			final RoomService roomService,
 			final UserService userService,
 			@Qualifier("defaultJsonMessageConverter") final
-			MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Answer.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Answer.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.answerRepository = repository;
 		this.roomService = roomService;
 		this.userService = userService;
diff --git a/src/main/java/de/thm/arsnova/service/AttachmentServiceImpl.java b/src/main/java/de/thm/arsnova/service/AttachmentServiceImpl.java
index d31955f1a9773b11dc57762c9a1cf463e4f1c8a4..a531c76148af3353946a6f6e0960bbdd9402e29a 100644
--- a/src/main/java/de/thm/arsnova/service/AttachmentServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/AttachmentServiceImpl.java
@@ -20,6 +20,7 @@ package de.thm.arsnova.service;
 
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.validation.Validator;
 import org.springframework.web.multipart.MultipartFile;
 
 import de.thm.arsnova.model.Attachment;
@@ -31,8 +32,9 @@ public class AttachmentServiceImpl extends DefaultEntityServiceImpl<Attachment>
 	public AttachmentServiceImpl(
 			final AttachmentRepository repository,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Attachment.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Attachment.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.attachmentRepository = repository;
 	}
 
diff --git a/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java b/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java
index a640924aea473e7621bf1e6cd88771b376a3ae48..e4471b29f014d1de1a8b03a24e811020ca80b8dd 100644
--- a/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java
@@ -29,6 +29,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.event.BeforeDeletionEvent;
 import de.thm.arsnova.model.Comment;
@@ -56,8 +57,9 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem
 			final RoomService roomService,
 			final UserService userService,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Comment.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Comment.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.commentRepository = repository;
 		this.roomService = roomService;
 		this.userService = userService;
diff --git a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java
index 4c003d790a4f0afff2c2aeb24cea7177413b6036..4321993f857e4ae52f833db4449a0190795e0d6d 100644
--- a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java
@@ -38,6 +38,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.event.BeforeDeletionEvent;
 import de.thm.arsnova.model.Content;
@@ -76,8 +77,9 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem
 			final LogEntryRepository dbLogger,
 			final UserService userService,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Content.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Content.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.contentRepository = repository;
 		this.roomService = roomService;
 		this.answerRepository = answerRepository;
diff --git a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
index dea9736b0f70898e896f09f52747512b23a4ae8e..731fba023f508c01f92999f52c53f8eca0ee64eb 100644
--- a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java
@@ -34,6 +34,9 @@ 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 org.springframework.validation.BeanPropertyBindingResult;
+import org.springframework.validation.Errors;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.event.AfterCreationEvent;
 import de.thm.arsnova.event.AfterDeletionEvent;
@@ -45,6 +48,7 @@ import de.thm.arsnova.event.BeforeDeletionEvent;
 import de.thm.arsnova.event.BeforeFullUpdateEvent;
 import de.thm.arsnova.event.BeforePatchEvent;
 import de.thm.arsnova.model.Entity;
+import de.thm.arsnova.model.EntityValidationException;
 import de.thm.arsnova.model.serialization.View;
 import de.thm.arsnova.persistence.CrudRepository;
 
@@ -60,12 +64,17 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 	protected CrudRepository<T, String> repository;
 	protected ApplicationEventPublisher eventPublisher;
 	private ObjectMapper objectMapper;
+	private Validator validator;
 
 	public DefaultEntityServiceImpl(
-			final Class<T> type, final CrudRepository<T, String> repository, final ObjectMapper objectMapper) {
+			final Class<T> type,
+			final CrudRepository<T, String> repository,
+			final ObjectMapper objectMapper,
+			final Validator validator) {
 		this.type = type;
 		this.repository = repository;
 		this.objectMapper = objectMapper;
+		this.validator = validator;
 	}
 
 	@Override
@@ -106,6 +115,7 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 
 		prepareCreate(entity);
 		eventPublisher.publishEvent(new BeforeCreationEvent<>(this, entity));
+		validate(entity);
 		final T createdEntity = repository.save(entity);
 		eventPublisher.publishEvent(new AfterCreationEvent<>(this, createdEntity));
 		finalizeCreate(createdEntity);
@@ -144,6 +154,7 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 
 		prepareUpdate(newEntity);
 		eventPublisher.publishEvent(new BeforeFullUpdateEvent<>(this, newEntity, oldEntity));
+		validate(newEntity);
 		final T updatedEntity = repository.save(newEntity);
 		eventPublisher.publishEvent(new AfterFullUpdateEvent<>(this, updatedEntity, oldEntity));
 		finalizeUpdate(updatedEntity);
@@ -186,6 +197,7 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 		entity.setUpdateTimestamp(new Date());
 		preparePatch(entity);
 		eventPublisher.publishEvent(new BeforePatchEvent<>(this, entity, propertyGetter, changes));
+		validate(entity);
 		final T patchedEntity = repository.save(entity);
 		eventPublisher.publishEvent(new AfterPatchEvent<>(this, patchedEntity, propertyGetter, changes));
 		modifyRetrieved(patchedEntity);
@@ -210,6 +222,7 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 			entity.setUpdateTimestamp(new Date());
 			preparePatch(entity);
 			eventPublisher.publishEvent(new BeforePatchEvent<>(this, entity, propertyGetter, changes));
+			validate(entity);
 		}
 
 		final Iterable<T> patchedEntities = repository.saveAll(entities);
@@ -272,6 +285,14 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService
 
 	}
 
+	protected void validate(final T entity) {
+		final Errors errors = new BeanPropertyBindingResult(entity, type.getName());
+		validator.validate(entity, errors);
+		if (errors.hasErrors()) {
+			throw new EntityValidationException(errors, entity);
+		}
+	}
+
 	public String getTypeName() {
 		return type.getSimpleName().toLowerCase();
 	}
diff --git a/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java b/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java
index e57202ff50620c46854cc11aab13f2a8090a9a25..3932c881be00cb2ad1260cd5a10df5ab2406b5c8 100644
--- a/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java
@@ -28,6 +28,7 @@ import org.springframework.cache.annotation.Cacheable;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.model.Motd;
 import de.thm.arsnova.model.Room;
@@ -50,8 +51,9 @@ public class MotdServiceImpl extends DefaultEntityServiceImpl<Motd> implements M
 			final UserService userService,
 			final RoomService roomService,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Motd.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Motd.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.motdRepository = repository;
 		this.userService = userService;
 		this.roomService = roomService;
diff --git a/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java b/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java
index 0bef23bacd870589636b41aaa77b3e0bea737a93..0ddfa42fb2372025da2f94d915b35e1b9b7dcd2a 100644
--- a/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java
@@ -40,6 +40,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.connector.client.ConnectorClient;
 import de.thm.arsnova.connector.model.Course;
@@ -98,8 +99,9 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R
 			final UserService userService,
 			final ScoreCalculatorFactory scoreCalculatorFactory,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(Room.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(Room.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.roomRepository = repository;
 		this.dbLogger = dbLogger;
 		this.userService = userService;
diff --git a/src/main/java/de/thm/arsnova/service/UserServiceImpl.java b/src/main/java/de/thm/arsnova/service/UserServiceImpl.java
index f8d2dd4072a8db7a7ab57e14cc0b323db16593a0..48ed77f620132206fcb7d64e94a08e18f1419e04 100644
--- a/src/main/java/de/thm/arsnova/service/UserServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/service/UserServiceImpl.java
@@ -64,6 +64,7 @@ import org.springframework.security.ldap.authentication.LdapAuthenticationProvid
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.Validator;
 import org.springframework.web.util.UriUtils;
 import org.stagemonitor.core.metrics.MonitorGauges;
 
@@ -152,8 +153,9 @@ public class UserServiceImpl extends DefaultEntityServiceImpl<UserProfile> imple
 			final AuthenticationProviderProperties authenticationProviderProperties,
 			final JavaMailSender mailSender,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
-		super(UserProfile.class, repository, jackson2HttpMessageConverter.getObjectMapper());
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
+		super(UserProfile.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator);
 		this.userRepository = repository;
 		this.securityProperties = securityProperties;
 		this.registeredProperties = authenticationProviderProperties.getRegistered();
diff --git a/src/test/java/de/thm/arsnova/config/TestAppConfig.java b/src/test/java/de/thm/arsnova/config/TestAppConfig.java
index cda6e61d222c635301f024db41256f093bcce00c..0ac92b12185fc080f7ebd1340bbff96196fd2ec0 100644
--- a/src/test/java/de/thm/arsnova/config/TestAppConfig.java
+++ b/src/test/java/de/thm/arsnova/config/TestAppConfig.java
@@ -42,6 +42,7 @@ import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.mock.web.MockServletContext;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.validation.Validator;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
 import de.thm.arsnova.persistence.UserRepository;
@@ -107,9 +108,10 @@ public class TestAppConfig {
 			final AuthenticationProviderProperties authenticationProviderProperties,
 			final JavaMailSender mailSender,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
 		return new StubUserService(repository, systemProperties, securityProperties, authenticationProviderProperties,
-				mailSender, jackson2HttpMessageConverter);
+				mailSender, jackson2HttpMessageConverter, validator);
 	}
 
 	@Bean
diff --git a/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java b/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java
index 852101f0e3ef6e4891cec048982bbd91635412cd..acc2c7e00306faa9ae4915028e3852114bce7a34 100644
--- a/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java
+++ b/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java
@@ -42,6 +42,7 @@ import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.config.AppConfig;
 import de.thm.arsnova.config.TestAppConfig;
@@ -65,6 +66,7 @@ import de.thm.arsnova.test.context.support.WithMockUser;
 		WebSocketConfig.class})
 @ActiveProfiles("test")
 public class StateEventDispatcherTest {
+	private static final String SOME_TEXT = "SomeText";
 	public static final String SETTINGS_PROPERTY_NAME = "settings";
 	public static final String STATE_PROPERTY_NAME = "state";
 	private static final String QUESTIONS_ENABLED_PROPERTY_NAME = "questionsEnabled";
@@ -79,6 +81,9 @@ public class StateEventDispatcherTest {
 	@Qualifier("defaultJsonMessageConverter")
 	private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
 
+	@Autowired
+	private Validator validator;
+
 	@Autowired
 	private ApplicationEventPublisher eventPublisher;
 
@@ -98,12 +103,13 @@ public class StateEventDispatcherTest {
 	public void testDispatchRoomSettingsStateEvent() throws IOException {
 		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
 		final DefaultEntityServiceImpl<Room> entityService = new DefaultEntityServiceImpl<>(
-				Room.class, roomRepository, objectMapper);
+				Room.class, roomRepository, objectMapper, validator);
 		entityService.setApplicationEventPublisher(eventPublisher);
 
 		when(roomRepository.save(any(Room.class))).then(returnsFirstArg());
 
 		final Room room = new Room();
+		prefillRoomFields(room);
 		room.setOwnerId(TEST_USER_ID);
 		entityService.patch(room, Collections.singletonMap(QUESTIONS_ENABLED_PROPERTY_NAME, false), Room::getSettings);
 		assertEquals(1, eventListenerConfig.getRoomSettingsStateChangeEvents().size());
@@ -115,22 +121,36 @@ public class StateEventDispatcherTest {
 	public void testDispatchContentStateEvent() throws IOException {
 		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
 		final DefaultEntityServiceImpl<Content> entityService = new DefaultEntityServiceImpl<>(
-				Content.class, contentRepository, objectMapper);
+				Content.class, contentRepository, objectMapper, validator);
 		entityService.setApplicationEventPublisher(eventPublisher);
 
 		final Room room = new Room();
+		prefillRoomFields(room);
 		room.setId(TEST_ROOM_ID);
 		room.setOwnerId(TEST_USER_ID);
 		when(contentRepository.save(any(Content.class))).then(returnsFirstArg());
 		when(roomRepository.findOne(eq(room.getId()))).thenReturn(room);
 
 		final Content content = new Content();
+		prefillContentFields(content);
 		content.setRoomId(room.getId());
 		entityService.patch(content, Collections.singletonMap(VISIBLE_PROPERTY_NAME, false), Content::getState);
 		assertEquals(1, eventListenerConfig.getContentStateChangeEvents().size());
 		assertEquals(STATE_PROPERTY_NAME, eventListenerConfig.getContentStateChangeEvents().get(0).getStateName());
 	}
 
+	private void prefillRoomFields(final Room room) {
+		room.setName(SOME_TEXT);
+		room.setAbbreviation(SOME_TEXT);
+		room.setShortId("12345678");
+	}
+
+	private void prefillContentFields(final Content content) {
+		content.setSubject(SOME_TEXT);
+		content.setBody(SOME_TEXT);
+		content.setFormat(Content.Format.CHOICE);
+	}
+
 	@Configuration
 	public static class EventListenerConfig {
 		private List<StateChangeEvent<Room, Room.Settings>> roomSettingsStateChangeEvents = new ArrayList<>();
diff --git a/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java b/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
index 84e64df881bac672ffcb2662de2b1b84bcb842e6..36260f0b988c670fd0608752276c80a04cae17bb 100644
--- a/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
+++ b/src/test/java/de/thm/arsnova/service/DefaultEntityServiceImplTest.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import javax.validation.ValidationException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,6 +44,7 @@ import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.config.AppConfig;
 import de.thm.arsnova.config.TestAppConfig;
@@ -64,10 +66,15 @@ import de.thm.arsnova.test.context.support.WithMockUser;
 		WebSocketConfig.class})
 @ActiveProfiles("test")
 public class DefaultEntityServiceImplTest {
+	private static final String SOME_TEXT = "SomeText";
+
 	@Autowired
 	@Qualifier("defaultJsonMessageConverter")
 	private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
 
+	@Autowired
+	private Validator validator;
+
 	@Autowired
 	private ApplicationEventPublisher eventPublisher;
 
@@ -82,7 +89,7 @@ public class DefaultEntityServiceImplTest {
 	public void testPatch() throws IOException {
 		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
 		final DefaultEntityServiceImpl<Room> entityService =
-				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper);
+				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper, validator);
 		entityService.setApplicationEventPublisher(eventPublisher);
 
 		when(roomRepository.save(any(Room.class))).then(returnsFirstArg());
@@ -92,6 +99,7 @@ public class DefaultEntityServiceImplTest {
 		final String originalOwnerId = "TestUser";
 		final boolean originalActive = true;
 		final Room room = new Room();
+		prefillRoomFields(room);
 		room.setId(originalId);
 		room.setName(originalName);
 		room.setClosed(originalActive);
@@ -117,7 +125,7 @@ public class DefaultEntityServiceImplTest {
 	public void testPatchWithList() throws IOException {
 		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
 		final DefaultEntityServiceImpl<Room> entityService =
-				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper);
+				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper, validator);
 		entityService.setApplicationEventPublisher(eventPublisher);
 
 		when(roomRepository.saveAll(anyListOf(Room.class))).then(returnsFirstArg());
@@ -128,6 +136,7 @@ public class DefaultEntityServiceImplTest {
 		final String originalOwnerId1 = "TestUser";
 		final boolean originalClosed1 = true;
 		final Room room1 = new Room();
+		prefillRoomFields(room1);
 		room1.setId(originalId1);
 		room1.setName(originalName1);
 		room1.setClosed(originalClosed1);
@@ -138,6 +147,7 @@ public class DefaultEntityServiceImplTest {
 		final String originalOwnerId2 = "TestUser";
 		final boolean originalClosed2 = true;
 		final Room room2 = new Room();
+		prefillRoomFields(room2);
 		room2.setId(originalId2);
 		room2.setName(originalName2);
 		room2.setClosed(originalClosed2);
@@ -168,19 +178,23 @@ public class DefaultEntityServiceImplTest {
 	public void testCaching() {
 		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
 		final DefaultEntityServiceImpl<Room> entityService =
-				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper);
+				new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper, validator);
 		entityService.setApplicationEventPublisher(eventPublisher);
 
 		final Room room1 = new Room();
+		prefillRoomFields(room1);
 		room1.setId("a34876427c634a9b9cb56789d73607f0");
 		room1.setOwnerId("TestUser");
 		final Room room2 = new Room();
+		prefillRoomFields(room2);
 		room2.setId("4638748d89884ff7936d7fe994a4090c");
 		room2.setOwnerId("TestUser");
 		final Room room3 = new Room();
+		prefillRoomFields(room3);
 		room3.setId("c9651db0a67b49789a354e90e0401032");
 		room3.setOwnerId("TestUser");
 		final Room room4 = new Room();
+		prefillRoomFields(room4);
 		room4.setId("66c1673056b2410b87335b9f317da5aa");
 		room4.setOwnerId("TestUser");
 
@@ -199,4 +213,27 @@ public class DefaultEntityServiceImplTest {
 		assertSame("Entity should not be cached.", null, cacheManager.getCache("entity").get("room-" + room1.getId()));
 		assertSame(room2, entityService.get(room1.getId()));
 	}
+
+	@Test(expected = ValidationException.class)
+	@WithMockUser("TestUser")
+	public void testValidation() {
+		final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
+		final DefaultEntityServiceImpl<Room> entityService =
+			new DefaultEntityServiceImpl<>(Room.class, roomRepository, objectMapper, validator);
+		entityService.setApplicationEventPublisher(eventPublisher);
+
+		when(roomRepository.save(any(Room.class))).then(returnsFirstArg());
+
+		final Room room1 = new Room();
+		room1.setOwnerId("TestUser");
+		room1.setName("");
+
+		entityService.create(room1);
+	}
+
+	private void prefillRoomFields(final Room room) {
+		room.setName(SOME_TEXT);
+		room.setAbbreviation(SOME_TEXT);
+		room.setShortId("12345678");
+	}
 }
diff --git a/src/test/java/de/thm/arsnova/service/StubUserService.java b/src/test/java/de/thm/arsnova/service/StubUserService.java
index d357ee521edb0709a26908d6015e138e9e7b6577..99a336cf3488bc61bc4f713c310f31d943b8b845 100644
--- a/src/test/java/de/thm/arsnova/service/StubUserService.java
+++ b/src/test/java/de/thm/arsnova/service/StubUserService.java
@@ -26,6 +26,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.validation.Validator;
 
 import de.thm.arsnova.config.properties.SystemProperties;
 import de.thm.arsnova.config.properties.AuthenticationProviderProperties;
@@ -45,9 +46,10 @@ public class StubUserService extends UserServiceImpl {
 			final AuthenticationProviderProperties authenticationProviderProperties,
 			final JavaMailSender mailSender,
 			@Qualifier("defaultJsonMessageConverter")
-			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {
+			final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter,
+			final Validator validator) {
 		super(repository, systemProperties, securityProperties, authenticationProviderProperties,
-				mailSender, jackson2HttpMessageConverter);
+				mailSender, jackson2HttpMessageConverter, validator);
 		grantedAuthorities = new HashSet<>();
 		grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
 	}