diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..bd42a82
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+ fr.plil.gis.sio
+ examen
+ 0.1
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.1.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
diff --git a/src/main/java/fr/plil/sio/examen/ExamenApplication.java b/src/main/java/fr/plil/sio/examen/ExamenApplication.java
new file mode 100644
index 0000000..634c249
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/ExamenApplication.java
@@ -0,0 +1,8 @@
+package fr.plil.sio.examen;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ExamenApplication {
+
+}
diff --git a/src/main/java/fr/plil/sio/examen/api/Animal.java b/src/main/java/fr/plil/sio/examen/api/Animal.java
new file mode 100644
index 0000000..c8b8da9
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/api/Animal.java
@@ -0,0 +1,52 @@
+package fr.plil.sio.examen.api;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+/**
+ * An animal must have a name one and only one owner
+ */
+@Entity
+public class Animal implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Column(nullable = false)
+ private String name;
+
+ @ManyToOne(optional = false)
+ private Owner owner;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Owner getOwner() {
+ return owner;
+ }
+
+ public void setOwner(Owner owner) {
+ this.owner = owner;
+ }
+
+
+}
diff --git a/src/main/java/fr/plil/sio/examen/api/Comment.java b/src/main/java/fr/plil/sio/examen/api/Comment.java
new file mode 100644
index 0000000..df00e44
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/api/Comment.java
@@ -0,0 +1,21 @@
+package fr.plil.sio.examen.api;
+
+/**
+ * A comment is made by an reporter (i.e. an owner) on ANY animal
+ * (not only the ones he owns).
+ * An reporter can have zero, one or more comments on any animal (i.e. it can
+ * exists several comments from the same reporter on the same animal).
+ * An animal can have zero, one or more comments by any reporter (i.e. it can
+ * exists several comments from the same reporter on the same animal).
+ *
+ * TODO: complete the classes in API to support comment serialization in the
+ * database.
+ */
+public class Comment {
+
+ private Owner reporter;
+
+ private Animal animal;
+
+ private String message;
+}
diff --git a/src/main/java/fr/plil/sio/examen/api/Owner.java b/src/main/java/fr/plil/sio/examen/api/Owner.java
new file mode 100644
index 0000000..4583923
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/api/Owner.java
@@ -0,0 +1,51 @@
+package fr.plil.sio.examen.api;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+/**
+ * An owner has a name and zero, one or more animals.
+ */
+@Entity
+public class Owner {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Column(nullable = false)
+ private String name;
+
+ @OneToMany(mappedBy = "owner")
+ private List animals = new LinkedList<>();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getAnimals() {
+ return animals;
+ }
+
+ public void setAnimals(List animals) {
+ this.animals = animals;
+ }
+}
diff --git a/src/main/java/fr/plil/sio/examen/repositories/AnimalRepository.java b/src/main/java/fr/plil/sio/examen/repositories/AnimalRepository.java
new file mode 100644
index 0000000..1159558
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/repositories/AnimalRepository.java
@@ -0,0 +1,15 @@
+package fr.plil.sio.examen.repositories;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Owner;
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AnimalRepository extends JpaRepository {
+
+ /**
+ * NOTE: this is an important example to help you with the findByXXX methods
+ * in the comment repository.
+ */
+ List findByOwner(Owner owner);
+}
diff --git a/src/main/java/fr/plil/sio/examen/repositories/CommentRepository.java b/src/main/java/fr/plil/sio/examen/repositories/CommentRepository.java
new file mode 100644
index 0000000..0b5666a
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/repositories/CommentRepository.java
@@ -0,0 +1,10 @@
+package fr.plil.sio.examen.repositories;
+
+import fr.plil.sio.examen.api.Comment;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * TODO: complete this interface for new find methods.
+ */
+public interface CommentRepository { //extends JpaRepository{
+}
diff --git a/src/main/java/fr/plil/sio/examen/repositories/OwnerRepository.java b/src/main/java/fr/plil/sio/examen/repositories/OwnerRepository.java
new file mode 100644
index 0000000..c70cc2a
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/repositories/OwnerRepository.java
@@ -0,0 +1,8 @@
+package fr.plil.sio.examen.repositories;
+
+import fr.plil.sio.examen.api.Owner;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface OwnerRepository extends JpaRepository{
+
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/AnimalService.java b/src/main/java/fr/plil/sio/examen/services/AnimalService.java
new file mode 100644
index 0000000..49babf3
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/AnimalService.java
@@ -0,0 +1,19 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Owner;
+
+public interface AnimalService {
+
+ /**
+ * Create an animal attached to an owner
+ */
+ Animal create(String name, Owner owner);
+
+ /**
+ * Delete an animal and ALL comment associated.
+ *
+ * TODO: complete this method.
+ */
+ void delete(Animal animal);
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/AnimalServiceImpl.java b/src/main/java/fr/plil/sio/examen/services/AnimalServiceImpl.java
new file mode 100644
index 0000000..3d66cdd
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/AnimalServiceImpl.java
@@ -0,0 +1,39 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Owner;
+import fr.plil.sio.examen.repositories.AnimalRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class AnimalServiceImpl implements AnimalService {
+
+ @Autowired
+ private AnimalRepository animalRepository;
+
+ @Override
+ @Transactional
+ public Animal create(String name, Owner owner) {
+ if(name == null) {
+ throw new IllegalArgumentException("name must be not null");
+ }
+ if(owner == null) {
+ throw new IllegalArgumentException("owner must be not null");
+ }
+ Animal animal = new Animal();
+ animal.setName(name);
+ animal.setOwner(owner);
+ animalRepository.save(animal);
+ return animal;
+ }
+
+
+ @Override
+ @Transactional
+ public void delete(Animal animal) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/CommentService.java b/src/main/java/fr/plil/sio/examen/services/CommentService.java
new file mode 100644
index 0000000..f1e08c1
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/CommentService.java
@@ -0,0 +1,34 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Comment;
+import fr.plil.sio.examen.api.Owner;
+import java.util.List;
+
+public interface CommentService {
+
+ /**
+ * Add a new comment (message) made by a reporter to an animal
+ */
+ Comment add(Owner reporter, Animal animal, String message);
+
+ /**
+ * Delete the comment
+ */
+ void delete(Comment comment);
+
+ /**
+ * List all messages about an animal
+ */
+ List findByAnimal(Animal animal);
+
+ /**
+ * List all messages reported by one owner
+ */
+ List findByReporter(Owner reporter);
+
+ /**
+ * List all messages about all animals of one owner
+ */
+ List findByOwner(Owner owner);
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/CommentServiceImpl.java b/src/main/java/fr/plil/sio/examen/services/CommentServiceImpl.java
new file mode 100644
index 0000000..cc60c48
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/CommentServiceImpl.java
@@ -0,0 +1,46 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Comment;
+import fr.plil.sio.examen.api.Owner;
+import java.util.List;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * TODO: complete all these methods
+ */
+@Service
+public class CommentServiceImpl implements CommentService {
+
+ @Override
+ @Transactional
+ public Comment add(Owner owner, Animal animal, String text) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ @Transactional
+ public void delete(Comment comment) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List findByAnimal(Animal animal) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List findByReporter(Owner reporter) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public List findByOwner(Owner owner) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/OwnerService.java b/src/main/java/fr/plil/sio/examen/services/OwnerService.java
new file mode 100644
index 0000000..791cfc7
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/OwnerService.java
@@ -0,0 +1,18 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Owner;
+
+public interface OwnerService {
+
+ /**
+ * Create an owner
+ */
+ Owner create(String name);
+
+ /**
+ * Delete an owner and ALL comment reporter by him/her.
+ *
+ * TODO: complete this method.
+ */
+ void delete(Owner owner);
+}
diff --git a/src/main/java/fr/plil/sio/examen/services/OwnerServiceImpl.java b/src/main/java/fr/plil/sio/examen/services/OwnerServiceImpl.java
new file mode 100644
index 0000000..8ee654c
--- /dev/null
+++ b/src/main/java/fr/plil/sio/examen/services/OwnerServiceImpl.java
@@ -0,0 +1,30 @@
+package fr.plil.sio.examen.services;
+
+import fr.plil.sio.examen.api.Owner;
+import fr.plil.sio.examen.repositories.OwnerRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class OwnerServiceImpl implements OwnerService {
+
+ @Autowired
+ private OwnerRepository ownerRepository;
+
+ @Override
+ public void delete(Owner owner) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ public Owner create(String name) {
+ if(name == null) {
+ throw new IllegalArgumentException("name must be not null");
+ }
+ Owner owner = new Owner();
+ owner.setName(name);
+ ownerRepository.save(owner);
+ return owner;
+ }
+
+}
diff --git a/src/test/java/fr/plil/sio/examen/AnimalRepositoryTest.java b/src/test/java/fr/plil/sio/examen/AnimalRepositoryTest.java
new file mode 100644
index 0000000..9b7d34b
--- /dev/null
+++ b/src/test/java/fr/plil/sio/examen/AnimalRepositoryTest.java
@@ -0,0 +1,36 @@
+package fr.plil.sio.examen;
+
+import fr.plil.sio.examen.api.Animal;
+import fr.plil.sio.examen.api.Owner;
+import fr.plil.sio.examen.repositories.AnimalRepository;
+import fr.plil.sio.examen.repositories.OwnerRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+@Transactional
+public class AnimalRepositoryTest {
+
+ @Autowired
+ private AnimalRepository animalRepository;
+
+ @Autowired
+ private OwnerRepository ownerRepository;
+
+ @Test
+ public void testSimpleOperations() {
+ Owner owner = new Owner();
+ owner.setName("mickey");
+ ownerRepository.save(owner);
+ Animal animal = new Animal();
+ animal.setName("pluto");
+ animal.setOwner(owner);
+ owner.getAnimals().add(animal);
+ animalRepository.save(animal);
+ }
+}
diff --git a/src/test/java/fr/plil/sio/examen/AnimalServiceTest.java b/src/test/java/fr/plil/sio/examen/AnimalServiceTest.java
new file mode 100644
index 0000000..2fd389e
--- /dev/null
+++ b/src/test/java/fr/plil/sio/examen/AnimalServiceTest.java
@@ -0,0 +1,29 @@
+package fr.plil.sio.examen;
+
+import fr.plil.sio.examen.api.Owner;
+import fr.plil.sio.examen.services.AnimalService;
+import fr.plil.sio.examen.services.OwnerService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+@Transactional
+public class AnimalServiceTest {
+
+ @Autowired
+ private AnimalService animalService;
+
+ @Autowired
+ private OwnerService ownerService;
+
+ @Test
+ public void createAnimalAndOwner() {
+ Owner o = ownerService.create("owner");
+ animalService.create("animal", o);
+ }
+}
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 0000000..e6e2446
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,5 @@
+logging.level.org.springframework=INFO
+logging.level.org.hibernate.SQL=DEBUG
+logging.level.org.hibernate=INFO
+spring.datasource.url=jdbc:h2:mem:persistence;TRACE_LEVEL_FILE=4;DB_CLOSE_ON_EXIT=FALSE
+spring.datasource.tomcat.max-active=500
--
libgit2 0.21.2