/* JPA (Java Persistence API) Transaction Management with an Entity-Mananger: --- entityManager.getTransaction().begin(); entityManager.persist(); 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 */ // 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; } // 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; // 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 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 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 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 persons = jdbcTemplate.query("select * from person", new BeanPropertyRowMapper(Person.class)); // Select a single object with JdbcTemplate Person person = jdbcTemplate.queryForObject("select * from person where id=?", new Object[] { 12 }, new BeanPropertyRowMapper(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