Revisions
-
jahe revised this gist
Jun 24, 2018 . 1 changed file with 20 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -387,4 +387,23 @@ public class Passport { public void createPerson() { em.persist(person1); // here the person gets its ID from the DB sequence, but the INSERT statement fires at the end of the transactional method person1.setName("Hans"); } // here does the INSERT happen and after that the transaction COMMIT // On a 1:n relationship the relating entity reference has to be set on both sides // But to add e.g. two new childs to a parent entity we only have to set the reference on both sides // and then call persist() only on the childs public void addReviewsForCourse() { Course course = em.find(Course.class, 1); Review goodReview = new Review("Super!"); Review badReview = new Review("Bad!"); course.addReview(goodReview); goodReview.setCourse(course); course.addReview(badReview); badReview.setCourse(course); em.persist(goodReview); em.persist(badReview); } -
jahe revised this gist
Jun 12, 2018 . 1 changed file with 12 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -106,6 +106,9 @@ public class Match { * Native Query - Plain SQL statements // Initialize DB schema in a Spring Boot App resources/schema.sql // Populate DB with data in a Spring Boot App resources/data.sql // Generic Rowmapper that maps all the columns to a Java Pojo @@ -376,4 +379,12 @@ public class Passport { @OneToOne(fetch=FetchType.LAZY, mappedBy="passport") private Student student; } // Hibernate tries to make the SQL statements as late as possible // In this case 1 x INSERT statement is being fired @Transactional public void createPerson() { em.persist(person1); // here the person gets its ID from the DB sequence, but the INSERT statement fires at the end of the transactional method person1.setName("Hans"); } // here does the INSERT happen and after that the transaction COMMIT -
jahe revised this gist
Jun 3, 2018 . 1 changed file with 43 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -334,4 +334,46 @@ public void foo() { // Use NativeQuery for mass updates Query nativeQuery = em.createNativeQuery("UPDATE person set last_updated_date=sysdate()"); int rowsAffected = nativeQuery.executeUpdate(); // Simple OneToOne relationship with one entity owning the relationship // // Fetch type of a @OneToOne relationship is "Eager" by default // This means that the passwort table will be joined in the select statement to find the student @Entity public class Student { @OneToOne private Passport passport; } // -> SELECT * FROM student ... LEFT OUTER JOIN passport ON ... // Set Fetch type to lazy so that the passport is only selected when it is needed @Entity public class Student { @OneToOne(fetch=FetchType.LAZY) private Passport passport; } Student student = em.find(Student.class, 1234); // -> SELECT * FROM student WHERE id=1234 String passportNumber = student.getPassport().getNumber(); // -> SELECT * FROM passport WHERE id=5678 // As soon as you introduce @Transactional a PersistenceContext will be created // The PersistenceContext is a place where every Entity is being stored // We interact with the PersistenceContext via an EntityManager (It is the interface to the PersistenceContext) // The PersistenceContext is created in the start of a transaction and killed when the transaction is ended // When there is no transaction, each method call to the EntityManager acts as an own transaction -> This is often the cause for a LazyInitializationException Hibernate "Session" == Persistence Context // Add mappedBy to the non-owning side of the relationship to get a biderectional navigation @Entity public class Passport { @OneToOne(fetch=FetchType.LAZY, mappedBy="passport") private Student student; } -
jahe revised this gist
May 29, 2018 . 1 changed file with 5 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -311,10 +311,14 @@ public void foo() { private LocalDateTime lastUpdatedDate; // Use NativeQuery to write plain SQL that is being executed directly // // Usecases for NativeQueries: // * Performance tuning // * DBMC specific features // * Mass updates (JPA can only select a row and then update that row) // // NativeQueries doesn't use the PersistenceContext // When you have some of the Entities that are being updated by a NativeQuery in your PersistenceContext you have to make sure to refresh() them. Query nativeQuery = em.createNativeQuery("SELECT * FROM person", Person.class); List<Person> persons = nativeQuery.getResultList(); @@ -330,4 +334,4 @@ public void foo() { // Use NativeQuery for mass updates Query nativeQuery = em.createNativeQuery("UPDATE person set last_updated_date=sysdate()"); int rowsAffected = nativeQuery.executeUpdate(); -
jahe revised this gist
May 29, 2018 . 1 changed file with 27 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -149,6 +149,10 @@ public Person findById(int id) { // Pretty print the SQL printed on the console spring.jpa.properties.hibernate.format_sql=true // Show SQL statistics of JPA / Hibernate (e.g. how long did a query take) spring.jpa.properties.hibernate.generate_statistics=true logging.level.org.hibernate.stat=debug // Find a JPA entity with EntityManager Person person = entityManager.find(Person.class, id) @@ -184,10 +188,6 @@ public class Person { TypedQuery<Person> typedQuery = entityManager.createQuery("select p from Person p", Person.class); List<Person> persons = typedQuery.getResultList(); // Reset In-Memory DB after a test method that changes the state of the DB @Test @DirtiesContext @@ -308,4 +308,26 @@ public void foo() { // Automatically insert a timestamp when an entity was updated (Hibernate specific) @UpdateTimestamp private LocalDateTime lastUpdatedDate; // Use NativeQuery to write plain SQL that is being executed directly // Usecases for NativeQueries: // * Performance tuning // * DBMC specific features // * Mass updates (JPA can only select a row and then update that row) Query nativeQuery = em.createNativeQuery("SELECT * FROM person", Person.class); List<Person> persons = nativeQuery.getResultList(); // Use NativeQuery with positional parameters Query nativeQuery = em.createNativeQuery("SELECT * FROM person WHERE id = ?", Person.class); nativeQuery.setParameter(1, 1234); List<Person> persons = nativeQuery.getResultList(); // Use NativeQuery with named parameters Query nativeQuery = em.createNativeQuery("SELECT * FROM person WHERE id = :id", Person.class); nativeQuery.setParameter("id", 1234); List<Person> persons = nativeQuery.getResultList(); // Use NativeQuery for mass updates Query nativeQuery = em.createNativeQuery("UPDATE person set last_updated_date=sysdate()"); int rowsAffected = nativeQuery.executeUpdate(); -
jahe revised this gist
May 29, 2018 . 1 changed file with 36 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -168,6 +168,22 @@ public class Person { ... } // Define multiple named queries on an entity @Entity @NamedQueries( value={ @NamedQuery(name="find_all_persons", query="select p from Person p"), @NamedQuery(name="find_all_persons_with_a", query="select p from Person p where name like 'a%'") } ) public class Person { ... } // Query the DB with a JPQL query TypedQuery<Person> typedQuery = entityManager.createQuery("select p from Person p", Person.class); List<Person> persons = typedQuery.getResultList(); // Show SQL statistics of JPA / Hibernate (e.g. how long did a query take) spring.jpa.properties.hibernate.generate_statistics=true logging.level.org.hibernate.stat=debug @@ -273,4 +289,23 @@ public void foo() { em.refresh(person); em.flush(); } // Specify column properties @Column( name="fullname", // Name of the table column - default: fieldname nullable=false, // Is the column nullable - default: true unique=true, // Is the value of this column unique across the table - default: false insertable=false, // Should this field be included in an INSERT command - default: true updateable=false, // Should this field be included in an UPDATE command - default: true length=20 // Maximum number of chars (only relevant to string fields) - default: 255 ) private String name; // Automatically insert a timestamp when an entity was created (Hibernate specific) @CreationTimestamp private LocalDateTime createdDate; // Automatically insert a timestamp when an entity was updated (Hibernate specific) @UpdateTimestamp private LocalDateTime lastUpdatedDate; -
jahe revised this gist
May 28, 2018 . No changes.There are no files selected for viewing
-
jahe revised this gist
May 26, 2018 . 1 changed file with 104 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -170,4 +170,107 @@ public class Person { // Show SQL statistics of JPA / Hibernate (e.g. how long did a query take) spring.jpa.properties.hibernate.generate_statistics=true logging.level.org.hibernate.stat=debug // Reset In-Memory DB after a test method that changes the state of the DB @Test @DirtiesContext public void deleteByIdBasic() { repository.deleteById(12); assertNull(repository.findById(12)); } // Save an Entity with JPA public Person save(Person person) { if (person.getId() == null) { // insert em.persist(person); } else { // update em.merge(person); } return person; } // In a @Transactional method every set-method results in an update of the row regardless of calling em.merge() on it // The EntityManager keeps track of all the changes that are being made to an Entity // In this case 1 x INSERT and 1 x UPDATE statement are being fired @Transactional public void foo() { Person person = new Person("Hansen"); em.persist(person); person.setName("Meier"); } // Send out changes to the DB within a Transaction // In this case 1 x INSERT and 2 x UPDATE statements are being fired @Transactional public void foo() { Person person = new Person("Hansen"); em.persist(person); em.flush(); person.setName("Meier"); em.flush(); person.setName("Raab"); em.flush(); } // Prevent changes made to an Entity from going into the DB within an Transaction // With em.detach(entity) the changes to this entity are no longer being tracked by the EntityManager // In this case 1 x INSERT and 1 x Update statements are being fired @Transactional public void foo() { Person person = new Person("Hansen"); em.persist(person); em.flush(); person.setName("Meier"); em.flush(); em.detach(person); person.setName("Raab"); } // Prevent changes made to all Entites from going into the DB within a Transaction // With em.clear() the changes to all entites are no longer being tracked by the EntityManager // In this case 2 x INSERT and no other statements are being fired @Transactional public void foo() { Person person = new Person("Hansen"); em.persist(person); Person person2 = new Person("Meier"); em.persist(person2); em.flush(); em.clear(); person.setName("Paulsen"); em.flush(); person2.setName("Raab"); em.flush(); } // Get a fresh copy of an Entity from the DB within a Transaction // All changes that are not being flushed are now lost @Transactional public void foo() { Person person = new Person("Hansen"); em.persist(person); Person person2 = new Person("Meier"); em.persist(person2); em.flush(); person.setName("Paulsen"); person2.setName("Raab"); em.refresh(person); em.flush(); } -
jahe revised this gist
May 26, 2018 . 1 changed file with 33 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -138,4 +138,36 @@ public Person findById(int id) { } // Activate H2 Web-Console spring.h2.console.enabled=true // Show SQL Statements made with JPA / Hibernate spring.jpa.show-sql=true // Show the parameters of the statements logging.level.org.hibernate.type=trace // Pretty print the SQL printed on the console spring.jpa.properties.hibernate.format_sql=true // Find a JPA entity with EntityManager Person person = entityManager.find(Person.class, id) // Insert or Update a JPA entity with EntityManager Person newPerson = entityManager.merge(person); // Delete a JPA entity with EntityManager entityManager.remove(person); // Find all entities with EntityManager (using JPQL -> It uses entites in its query, not table names) TypedQuery<Person> namedQuery = entityManager.createNamedQuery("find_all_persons", Person.class); List<Person> persons = namedQuery.getResultList(); @Entity @NamedQuery(name="find_all_persons", query="select p from Person p") public class Person { ... } // Show SQL statistics of JPA / Hibernate (e.g. how long did a query take) spring.jpa.properties.hibernate.generate_statistics=true logging.level.org.hibernate.stat=debug -
jahe revised this gist
May 26, 2018 . No changes.There are no files selected for viewing
-
jahe revised this gist
May 26, 2018 . 1 changed file with 30 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -109,4 +109,33 @@ public class Match { resources/data.sql // Generic Rowmapper that maps all the columns to a Java Pojo List<Person> persons = jdbcTemplate.query("select * from person", new BeanPropertyRowMapper<Person>(Person.class)); // Select a single object with JdbcTemplate Person person = jdbcTemplate.queryForObject("select * from person where id=?", new Object[] { 12 }, new BeanPropertyRowMapper<Person>(Person.class)); // Delete a single object with JdbcTemplate int rowsAffected = jdbcTemplate.update("delete * from person where id=?", new Object[] { 12 }); // Insert a single object with JdbcTemplate (java.sql.Timestamp) int rowsAffected = jdbcTemplate.update("insert into person (id, name, birth_date) values (?, ?)", new Object[] { 12, "Meier", new Timestamp(new Date().getTime()) }); // Update a single object with JdbcTemplate int rowsAffected = jdbcTemplate.update("update person set name=? where id=?", new Object[] { "Petersen", 12 }); EntityManger = Interface to the PersistenceContext // Enable Transaction Management on each method @Transactional // javax.persistence.Transactional public class PersonJpaRepository { @PersistenceContext EntityManager entitiyManager; public Person findById(int id) { return entityManager.find(Person.class, id); } } // Activate H2 Web-Console spring.h2.console.enabled=true -
jahe revised this gist
May 25, 2018 . 1 changed file with 13 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -97,4 +97,16 @@ public class Match { // Several ways to delete records in the db // http://www.objectdb.com/java/jpa/persistence/delete#Orphan_Removal TODO: how to implemwnt equals and hashcode: https://vladmihalcea.com/2016/10/20/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/ Query Data * JDBC - Plain SQL statements * JPQL - Query language based on Enitity names (not on table names) * Criteria Query - Build a query with a Java based API * Native Query - Plain SQL statements // Initialize DB schema in a Spring Boot App resources/data.sql // Generic Rowmapper that maps all the columns to a Java Pojo List<Person> persons = jdbcTemplate.query("select * from person", new BeanPropertyRowMapper<Person>(Person.class)) -
jahe revised this gist
Jun 24, 2017 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -95,4 +95,6 @@ public class Match { // CascadeType.ALL contains PERSIST, REMOVE, REFRESH, MERGE, DETACH // Several ways to delete records in the db // http://www.objectdb.com/java/jpa/persistence/delete#Orphan_Removal TODO: how to implemwnt equals and hashcode: https://vladmihalcea.com/2016/10/20/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/ -
jahe revised this gist
Jun 23, 2017 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ /* JPA (Java Persistence API) Transaction Management with an Entity-Mananger: @@ -44,6 +45,7 @@ Lazy Loading funktioniert Detached - Lazy Loading muss nicht zwangsweise funktionieren */ // Use a database sequence on id field @Entity @@ -93,4 +95,4 @@ public class Match { // CascadeType.ALL contains PERSIST, REMOVE, REFRESH, MERGE, DETACH // Several ways to delete records in the db // http://www.objectdb.com/java/jpa/persistence/delete#Orphan_Removal -
jahe revised this gist
Jun 23, 2017 . 1 changed file with 41 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -49,19 +49,48 @@ @Entity @Table(name = "ADDRESS") public class Address { @Id @SequenceGenerator( name = "address_seq", sequenceName = "address_seq", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "address_seq" ) private long id; } // Delete dependent children, when the parent is going to be deleted (child-entites are orphans (=Waisen) then) @OneToMany(mappedBy="foo", orphanRemoval=true) private List<Bikes> bikes; // Model a m:n relationship where the corresponding relationship record would be deleted when a entity record is deleted @Entity public class Team { @ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, mappedBy="teams") private List<Match> matches; } @Entity public class Match { @ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }) @JoinTable( name="MATCH_TEAM", joinColumns={@JoinColumn(name="MATCH_ID", referencedColumnName="ID")}, inverseJoinColumns={@JoinColumn(name="TEAM_ID", referencedColumnName="ID")} ) private List<Team> teams; } // Remove Child Records, when the child record is set to null in the parents collection of children // by setting "orphanRemoval = true" @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true) private AvatarImage avatarImage; // Mark children elements as "CascadeType.ALL" to refresh/delete/... them if the parent refreshes/deletes/... // CascadeType.ALL contains PERSIST, REMOVE, REFRESH, MERGE, DETACH // Several ways to delete records in the db http://www.objectdb.com/java/jpa/persistence/delete#Orphan_Removal -
jahe revised this gist
Jun 23, 2017 . 1 changed file with 5 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -60,4 +60,8 @@ public class Address { generator = "address_seq" ) private long id; } // Delete dependent children, when the parent is going to be deleted (child-entites are orphans (=Waisen) then) @OneToMany(mappedBy="foo", orphanRemoval=true) private List<Bikes> bikes; -
jahe renamed this gist
May 24, 2017 . 1 changed file with 18 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,4 +43,21 @@ Beim nächsten Transaktions-Commit werden nur die Änderungen in die DB geschrieben. Lazy Loading funktioniert Detached - Lazy Loading muss nicht zwangsweise funktionieren // Use a database sequence on id field @Entity @Table(name = "ADDRESS") public class Address { @Id @SequenceGenerator( name = "address_seq", sequenceName = "address_seq", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "address_seq" ) private long id; } -
jahe created this gist
May 12, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ JPA (Java Persistence API) Transaction Management with an Entity-Mananger: --- entityManager.getTransaction().begin(); entityManager.persist(<some-entity>); entityManager.getTransaction().commit(); entityManager.clear(); SomeEntity entity = entityManager.find(SomeEntity.class, 1); --- @OneToOne's fetch type is EAGER by default Lists + Sets fetch type is LAZY by default Two types of Lazy Loading implementations 1. Proxying the object (default in Hibernate) by creating a Subclass of that object at runtime and overwrite the get methods. This is done by the JavaAssist lib. 2. ByteCode Enhancement (default in EclipseLink): Add special logic to the get methods inside the Java Bytecode LazyInitializationExcepiton: Entity Lifecycle New ---> em.persist ---> Managed New ---> em.merge ---> Managed Managed ---> em.remove ---> Removed Managed ---> em.find ---> Managed Managed ---> query.getResultList ---> Managed Managed ---> query.getSingleResult ---> Managed Managed ---> em.detach ---> Detached Managed ---> em.close ---> Detached Managed ---> em.clear ---> Detached Detached ---> em.merge ---> Managed Ein neu angelegtes Entity Object ist im Zustand "New". Managed - Es gibt einen Entity-Manager, der für dieses Objekt verantwortlich ist: Vorteile: - Es werden automatisch Änderungen getrackt. Beim nächsten Transaktions-Commit werden nur die Änderungen in die DB geschrieben. Lazy Loading funktioniert Detached - Lazy Loading muss nicht zwangsweise funktionieren