{"id":20380,"date":"2014-01-09T16:00:03","date_gmt":"2014-01-09T14:00:03","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=20380"},"modified":"2014-01-09T08:07:12","modified_gmt":"2014-01-09T06:07:12","slug":"project-student-sharding-integration-test-data","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html","title":{"rendered":"Project Student: Sharding Integration Test Data"},"content":{"rendered":"<p>This is part of <a href=\"http:\/\/invariantproperties.com\/2013\/12\/10\/project-student\/\">Project Student<\/a>. Other posts are <a href=\"http:\/\/www.javacodegeeks.com\/2013\/12\/project-student-webservice-client-with-jersey.html\">Webservice Client With Jersey<\/a>, <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-server-with-jersey.html\">Webservice Server with Jersey<\/a>, <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-business-layer.html\">Business Layer<\/a> and <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-persistence-with-spring-data.html\">Persistence with Spring Data<\/a>.<\/p>\n<p>All of the integration tests until now have used an in-memory embedded database that did not retain information from run to run. This changes when we fully integrate the REST server with a \u201creal\u201d database server \u2013 leftover test data will pollute our development or test database. This can be a real headache once we have continuous integration that runs integration tests code is checked in.<\/p>\n<p>One solution is to \u2018shard\u2019 our integration test data in a way that allows our tests to use the shared development database without polluting it or other tests. The easiest approach is to add a <em>TestRun<\/em> field to all of our objects. \u201cTest\u201d data will have a value that indicates the specific test run, \u201clive\u201d data will have a null value.<\/p>\n<p>The exact timeline is<\/p>\n<ol>\n<li>create and persist a TestRun object<\/li>\n<li>create test objects with appropriate TestRun value<\/li>\n<li>perform the integration tests<\/li>\n<li>delete the test objects<\/li>\n<li>delete the TestRun object<\/li>\n<\/ol>\n<p>Any entry in the TestRun table will either be 1) active integration tests or 2) failed integration tests that threw an unhandled exception (depending upon the transaction manager, of course). It\u2019s important to note that we can also capture the database state after an unexpected exception is thrown even if the transaction manager performs a rollback \u2013 it\u2019s a simple extension to the junit test runner.<\/p>\n<p>Timestamp and user fields make it easy to delete stale test data according to its age (e.g., any test more than 7 days old) or the person who ran the test.<\/p>\n<h2>TestablePersistentObject abstract base class<\/h2>\n<p>This change starts at the persistence level so we should start there and work our way outwards.<\/p>\n<p>We first extend our PersistentObject abstract base class with a test run value.<\/p>\n<pre class=\" brush:java\">@MappedSuperclass\r\npublic abstract class TestablePersistentObject extends PersistentObject {\r\n    private static final long serialVersionUID = 1L;\r\n    private TestRun testRun;\r\n\r\n    \/**\r\n     * Fetch testRun object. We use lazy fetching since we rarely care about the\r\n     * contents of this object - we just want to ensure referential integrity to\r\n     * an existing testRun object when persisting a TPO.\r\n     * \r\n     * @return\r\n     *\/\r\n    @ManyToOne(fetch = FetchType.LAZY, optional = true)\r\n    public TestRun getTestRun() {\r\n        return testRun;\r\n    }\r\n\r\n    public void setTestRun(TestRun testRun) {\r\n        this.testRun = testRun;\r\n    }\r\n\r\n    @Transient\r\n    public boolean isTestData() {\r\n        return testRun != null;\r\n    }\r\n}<\/pre>\n<h2>TestRun class<\/h2>\n<p>The TestRun class contains identifying information about a single integration test run. It contains a name (by default the <em>classname#methodname()<\/em> of the surrounding integration test), the date and time of the test, and the name of the user running the test. It would be easy to capture additional information.<\/p>\n<p>The list of test objects gives us two big wins. First, it makes it easy to capture the state of the database if needed (e.g., after an unexpected exception). Second, cascading deletions makes it easy to delete all test objects.<\/p>\n<pre class=\" brush:java\">@XmlRootElement\r\n@Entity\r\n@Table(name = \"test_run\")\r\n@AttributeOverride(name = \"id\", column = @Column(name = \"test_run_pkey\"))\r\npublic class TestRun extends PersistentObject {\r\n    private static final long serialVersionUID = 1L;\r\n\r\n    private String name;\r\n    private Date testDate;\r\n    private String user;\r\n    private List&lt;TestablePersistentObject&gt; objects = Collections.emptyList();\r\n\r\n    @Column(length = 80, unique = false, updatable = true)\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    public void setName(String name) {\r\n        this.name = name;\r\n    }\r\n\r\n    @Column(name = \"test_date\", nullable = false, updatable = false)\r\n    @Temporal(TemporalType.TIMESTAMP)\r\n    public Date getTestDate() {\r\n        return testDate;\r\n    }\r\n\r\n    public void setTestDate(Date testDate) {\r\n        this.testDate = testDate;\r\n    }\r\n\r\n    @Column(length = 40, unique = false, updatable = false)\r\n    public String getUser() {\r\n        return user;\r\n    }\r\n\r\n    public void setUser(String user) {\r\n        this.user = user;\r\n    }\r\n\r\n    @OneToMany(cascade = CascadeType.ALL)\r\n    public List&lt;TestablePersistentObject&gt; getObjects() {\r\n        return objects;\r\n    }\r\n\r\n    public void setObjects(List&lt;TestablePersistentObject&gt; objects) {\r\n        this.objects = objects;\r\n    }\r\n\r\n    \/**\r\n     * This is similar to standard prepersist method but we also set default\r\n     * values for everything else.\r\n     *\/\r\n    @PrePersist\r\n    public void prepersist() {\r\n        if (getCreationDate() == null) {\r\n            setCreationDate(new Date());\r\n        }\r\n\r\n        if (getTestDate() == null) {\r\n            setTestDate(new Date());\r\n        }\r\n\r\n        if (getUuid() == null) {\r\n            setUuid(UUID.randomUUID().toString());\r\n        }\r\n\r\n        if (getUser() == null) {\r\n            setUser(System.getProperty(\"user.name\"));\r\n        }\r\n\r\n        if (name == null) {\r\n            setName(\"test run \" + getUuid());\r\n        }\r\n    }\r\n}<\/pre>\n<p>The TestRun class extends PersistentObject, not TestablePersistentObject, since our other integration tests will sufficiently exercise it.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h2>Spring Data Repository<\/h2>\n<p>We must add one additional method to every Repository.<\/p>\n<pre class=\" brush:java\">@Repository\r\npublic interface CourseRepository extends JpaRepository {\r\n    List&lt;Course&gt; findCoursesByTestRun(TestRun testRun);\r\n\r\n    ....\r\n}<\/pre>\n<h2>Service Interface<\/h2>\n<p>Likewise we must add two additional methods to every service.<\/p>\n<pre class=\" brush:java\">public interface CourseService {\r\n    List&lt;Course&gt; findAllCourses();\r\n\r\n    Course findCourseById(Integer id);\r\n\r\n    Course findCourseByUuid(String uuid);\r\n\r\n    Course createCourse(String name);\r\n\r\n    Course updateCourse(Course course, String name);\r\n\r\n    void deleteCourse(String uuid);\r\n\r\n    \/\/ new method for testing\r\n    Course createCourseForTesting(String name, TestRun testRun);\r\n\r\n    \/\/ new method for testing\r\n    List&lt;Course&gt; findAllCoursesForTestRun(TestRun testRun);\r\n}<\/pre>\n<p>I won\u2019t show the TestRunRepository, the TestRunService interface, or the TestRunService implementation since they\u2019re identical to what I\u2019ve described in the last few blog entries.<\/p>\n<h2>Service Implementation<\/h2>\n<p>We have to make one small change to an existing Service implementation, plus add two new methods.<\/p>\n<pre class=\" brush:java\">@Service\r\npublic class CourseServiceImpl implements CourseService {\r\n    @Resource\r\n    private TestRunService testRunService;\r\n\r\n    \/**\r\n     * @see com.invariantproperties.sandbox.student.business.CourseService#\r\n     *      findAllCourses()\r\n     *\/\r\n    @Transactional(readOnly = true)\r\n    @Override\r\n    public List&lt;Course&gt; findAllCourses() {\r\n        List&lt;Course&gt; courses = null;\r\n\r\n        try {\r\n            courses = courseRepository.findCoursesByTestRun(null);\r\n        } catch (DataAccessException e) {\r\n            if (!(e instanceof UnitTestException)) {\r\n                log.info(\"error loading list of courses: \" + e.getMessage(), e);\r\n            }\r\n            throw new PersistenceException(\"unable to get list of courses.\", e);\r\n        }\r\n\r\n        return courses;\r\n    }\r\n\r\n    \/**\r\n     * @see com.invariantproperties.sandbox.student.business.CourseService#\r\n     *      findAllCoursesForTestRun(com.invariantproperties.sandbox.student.common.TestRun)\r\n     *\/\r\n    @Transactional(readOnly = true)\r\n    @Override\r\n    public List&lt;Course&gt; findAllCoursesForTestRun(TestRun testRun) {\r\n        List&lt;Course&gt; courses = null;\r\n\r\n        try {\r\n            courses = courseRepository.findCoursesByTestRun(testRun);\r\n        } catch (DataAccessException e) {\r\n            if (!(e instanceof UnitTestException)) {\r\n                log.info(\"error loading list of courses: \" + e.getMessage(), e);\r\n            }\r\n            throw new PersistenceException(\"unable to get list of courses.\", e);\r\n        }\r\n\r\n        return courses;\r\n    }\r\n\r\n    \/**\r\n     * @see com.invariantproperties.sandbox.student.business.CourseService#\r\n     *      createCourseForTesting(java.lang.String,\r\n     *      com.invariantproperties.sandbox.student.common.TestRun)\r\n     *\/\r\n    @Transactional\r\n    @Override\r\n    public Course createCourseForTesting(String name, TestRun testRun) {\r\n        final Course course = new Course();\r\n        course.setName(name);\r\n        course.setTestUuid(testRun.getTestUuid());\r\n\r\n        Course actual = null;\r\n        try {\r\n            actual = courseRepository.saveAndFlush(course);\r\n        } catch (DataAccessException e) {\r\n            if (!(e instanceof UnitTestException)) {\r\n                log.info(\"internal error retrieving course: \" + name, e);\r\n            }\r\n            throw new PersistenceException(\"unable to create course\", e);\r\n        }\r\n\r\n        return actual;\r\n    }\r\n}<\/pre>\n<h2>CourseServiceIntegrationTest<\/h2>\n<p>We make a few changes to our integration tests. We only have to change one test method since it\u2019s the only one that actually creates a test object. The rest of the methods are queries that don\u2019t require test data.<\/p>\n<p>Note that we change the <em>name<\/em> value to ensure it\u2019s unique. This is a way to work around uniqueness constraints, e.g., for email addresses.<\/p>\n<pre class=\" brush:java\">@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = { BusinessApplicationContext.class, TestBusinessApplicationContext.class,\r\n        TestPersistenceJpaConfig.class })\r\n@Transactional\r\n@TransactionConfiguration(defaultRollback = true)\r\npublic class CourseServiceIntegrationTest {\r\n\r\n    @Resource\r\n    private CourseService dao;\r\n\r\n    @Resource\r\n    private TestRunService testService;\r\n\r\n    @Test\r\n    public void testCourseLifecycle() throws Exception {\r\n        final TestRun testRun = testService.createTestRun();\r\n\r\n        final String name = \"Calculus 101 : \" + testRun.getUuid();\r\n\r\n        final Course expected = new Course();\r\n        expected.setName(name);\r\n\r\n        assertNull(expected.getId());\r\n\r\n        \/\/ create course\r\n        Course actual = dao.createCourseForTesting(name, testRun);\r\n        expected.setId(actual.getId());\r\n        expected.setUuid(actual.getUuid());\r\n        expected.setCreationDate(actual.getCreationDate());\r\n\r\n        assertThat(expected, equalTo(actual));\r\n        assertNotNull(actual.getUuid());\r\n        assertNotNull(actual.getCreationDate());\r\n\r\n        \/\/ get course by id\r\n        actual = dao.findCourseById(expected.getId());\r\n        assertThat(expected, equalTo(actual));\r\n\r\n        \/\/ get course by uuid\r\n        actual = dao.findCourseByUuid(expected.getUuid());\r\n        assertThat(expected, equalTo(actual));\r\n\r\n        \/\/ get all courses\r\n        final List&lt;Course&gt; courses = dao.findCoursesByTestRun(testRun);\r\n        assertTrue(courses.contains(actual));\r\n\r\n        \/\/ update course\r\n        expected.setName(\"Calculus 102 : \" + testRun.getUuid());\r\n        actual = dao.updateCourse(actual, expected.getName());\r\n        assertThat(expected, equalTo(actual));\r\n\r\n        \/\/ verify testRun.getObjects\r\n        final List&lt;TestablePersistentObject&gt; objects = testRun.getObjects();\r\n        assertTrue(objects.contains(actual));\r\n\r\n        \/\/ delete Course\r\n        dao.deleteCourse(expected.getUuid());\r\n        try {\r\n            dao.findCourseByUuid(expected.getUuid());\r\n            fail(\"exception expected\");\r\n        } catch (ObjectNotFoundException e) {\r\n            \/\/ expected\r\n        }\r\n\r\n        testService.deleteTestRun(testRun.getUuid());\r\n    }\r\n\r\n    ....\r\n}<\/pre>\n<p>We could use <em>@Before<\/em> and <em>@After<\/em> to transparently wrap all test methods but many tests don\u2019t require test data and many tests that do require test data require unique test data, e.g., for email addresses. In the latter case we fold in the Test UUID as above.<\/p>\n<h2>REST Webservice Server<\/h2>\n<p>The REST webservice requires adding a test uuid to the request classes and adding a bit of logic to properly handle it when creating an object.<\/p>\n<p>The REST webservice does not support getting a list of all test objects. The \u201ccorrect\u201d approach will be creating a TestRun service and providing associated objects in response to a \/get\/{id} query.<\/p>\n<pre class=\" brush:java\">@XmlRootElement\r\npublic class Name {\r\n    private String name;\r\n    private String testUuid;\r\n\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    public void setName(String name) {\r\n        this.name = name;\r\n    }\r\n\r\n    public String getTestUuid() {\r\n        return testUuid;\r\n    }\r\n\r\n    public void setTestUuid(String testUuid) {\r\n        this.testUuid = testUuid;\r\n    }\r\n}<\/pre>\n<p>We can now check for the optional testUuid field and call the appropriate create method.<\/p>\n<pre class=\" brush:java\">@Service\r\n@Path(\"\/course\")\r\npublic class CourseResource extends AbstractResource {\r\n    @Resource\r\n    private CourseService service;\r\n\r\n    @Resource\r\n    private TestRunService testRunService;\r\n\r\n    \/**\r\n     * Create a Course.\r\n     * \r\n     * @param req\r\n     * @return\r\n     *\/\r\n    @POST\r\n    @Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })\r\n    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })\r\n    public Response createCourse(Name req) {\r\n        log.debug(\"CourseResource: createCourse()\");\r\n\r\n        final String name = req.getName();\r\n        if ((name == null) || name.isEmpty()) {\r\n            return Response.status(Status.BAD_REQUEST).entity(\"'name' is required'\").build();\r\n        }\r\n\r\n        Response response = null;\r\n\r\n        try {\r\n            Course course = null;\r\n\r\n            if (req.getTestUuid() != null) {\r\n                TestRun testRun = testRunService.findTestRunByUuid(req.getTestUuid());\r\n                if (testRun != null) {\r\n                    course = service.createCourseForTesting(name, testRun);\r\n                } else {\r\n                    response = Response.status(Status.BAD_REQUEST).entity(\"unknown test UUID\").build();\r\n                }\r\n            } else {\r\n                course = service.createCourse(name);\r\n            }\r\n            if (course == null) {\r\n                response = Response.status(Status.INTERNAL_SERVER_ERROR).build();\r\n            } else {\r\n                response = Response.created(URI.create(course.getUuid())).entity(scrubCourse(course)).build();\r\n            }\r\n        } catch (Exception e) {\r\n            if (!(e instanceof UnitTestException)) {\r\n                log.info(\"unhandled exception\", e);\r\n            }\r\n            response = Response.status(Status.INTERNAL_SERVER_ERROR).build();\r\n        }\r\n\r\n        return response;\r\n    }\r\n\r\n    ....\r\n}<\/pre>\n<h2>REST Webservice Client<\/h2>\n<p>Finally the REST server must add one additional method. The client does not support getting a list of all test objects yet.<\/p>\n<pre class=\" brush:java\">public interface CourseRestClient {\r\n\r\n    \/**\r\n     * Create specific course for testing.\r\n     * \r\n     * @param name\r\n     * @param testRun\r\n     *\/\r\n    Course createCourseForTesting(String name, TestRun testRun);\r\n\r\n    ....\r\n}<\/pre>\n<p>and<\/p>\n<pre class=\" brush:java\">public class CourseRestClientImpl extends AbstractRestClientImpl implements CourseRestClient {\r\n\r\n    \/**\r\n     * Create JSON string.\r\n     * \r\n     * @param name\r\n     * @return\r\n     *\/\r\n    String createJson(final String name, final TestRun testRun) {\r\n        return String.format(\"{ \\\"name\\\": \\\"%s\\\", \\\"testUuid\\\": \\\"%s\\\" }\", name, testRun.getTestUuid());\r\n    }\r\n\r\n    \/**\r\n     * @see com.invariantproperties.sandbox.student.webservice.client.CourseRestClient#createCourse(java.lang.String)\r\n     *\/\r\n    @Override\r\n    public Course createCourseForTesting(final String name, final TestRun testRun) {\r\n        if (name == null || name.isEmpty()) {\r\n            throw new IllegalArgumentException(\"'name' is required\");\r\n        }\r\n\r\n        if (testRun == null || testRun.getTestUuid() == null || testRun.getTestUuid().isEmpty()) {\r\n            throw new IllegalArgumentException(\"'testRun' is required\");\r\n        }\r\n\r\n        return createObject(createJson(name, testRun));\r\n    }\r\n\r\n    ....\r\n}<\/pre>\n<h2>Source Code<\/h2>\n<p>The source code is available at <a href=\"http:\/\/code.google.com\/p\/invariant-properties-blog\/source\/browse\/student\">http:\/\/code.google.com\/p\/invariant-properties-blog\/source\/browse\/student<\/a>.<\/p>\n<h2>Clarification<\/h2>\n<p>I didn\u2019t think it was possible to have a @OneToMany to TestablePersistentObject in TestRun but the integration tests using H2 succeeded. Unfortunately it\u2019s causing problems as I bring up the fully integrated webservice with a PostgreSQL database. I\u2019m leaving the code in place above since it\u2019s always possible to have a list of Classrooms, a list of Courses, etc., even if we can\u2019t have a generic collection. However the code is being removed from the version under source control.<\/p>\n<h2>Correction<\/h2>\n<p>The interface method should be <em>findCourseByTestRun_Uuid()<\/em>, not <em>findCourseByTestRun()<\/em>. Another approach is using JPA criteria queries \u2013 see <a href=\"http:\/\/invariantproperties.com\/2013\/12\/29\/project-student-jpa-criteria-queries\/\">Project Student: JPA Criteria Queries<\/a>.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/invariantproperties.com\/2013\/12\/23\/project-student-sharding-integration-test-data\/\">Project Student: Sharding Integration Test Data<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Bear Giles at the <a href=\"http:\/\/invariantproperties.com\/\">Invariant Properties<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring Data. All of the integration tests until now have used an in-memory embedded database that did not retain information from run to run. This changes when we fully integrate the REST server &hellip;<\/p>\n","protected":false},"author":113,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,273],"class_list":["post-20380","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-testing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Project Student: Sharding Integration Test Data<\/title>\n<meta name=\"description\" content=\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Project Student: Sharding Integration Test Data\" \/>\n<meta property=\"og:description\" content=\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-01-09T14:00:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Bear Giles\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bear Giles\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html\"},\"author\":{\"name\":\"Bear Giles\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/91196fd6369bac9f4ec7217ffbca53f9\"},\"headline\":\"Project Student: Sharding Integration Test Data\",\"datePublished\":\"2014-01-09T14:00:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html\"},\"wordCount\":860,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Testing\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html\",\"name\":\"Project Student: Sharding Integration Test Data\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2014-01-09T14:00:03+00:00\",\"description\":\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-sharding-integration-test-data.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Project Student: Sharding Integration Test Data\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/91196fd6369bac9f4ec7217ffbca53f9\",\"name\":\"Bear Giles\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"caption\":\"Bear Giles\"},\"sameAs\":[\"http:\\\/\\\/invariantproperties.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Bear-Giles\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Project Student: Sharding Integration Test Data","description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html","og_locale":"en_US","og_type":"article","og_title":"Project Student: Sharding Integration Test Data","og_description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring","og_url":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2014-01-09T14:00:03+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Bear Giles","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bear Giles","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html"},"author":{"name":"Bear Giles","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/91196fd6369bac9f4ec7217ffbca53f9"},"headline":"Project Student: Sharding Integration Test Data","datePublished":"2014-01-09T14:00:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html"},"wordCount":860,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Testing"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html","url":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html","name":"Project Student: Sharding Integration Test Data","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2014-01-09T14:00:03+00:00","description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer and Persistence with Spring","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Project Student: Sharding Integration Test Data"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/91196fd6369bac9f4ec7217ffbca53f9","name":"Bear Giles","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","caption":"Bear Giles"},"sameAs":["http:\/\/invariantproperties.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Bear-Giles"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20380","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/113"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=20380"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20380\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=20380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=20380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=20380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}