# JDBC, JPA, Hibernate

## Spring with JDBC

```java
@Repository
class PersonJdbcDao {

    @Autowired
    JdbcTemplate template;
    
    public List<Person> findAll() {
        return template.query("select * from person", 
            new BeanPropertyRowMapper(Person.class));
    }
}
```

## Spring with JPA EntityManager

```java
@Transactional
@Repository
class SomeRepository {

    @Autowired
    EntityManager manager;
    
    public SomeClass findById(Long id) {
        return manager.find(SomeClass.class, id);
    }
    
    public void createAndUpdate(Course course) {
        manager.persist(course); // entity is stored in db
        course.setName("new name");
        // even though I do not ask explicitly to merge 
        // the entity in db => entity is updated
        // because the method is declared to be transactional
    }
    
    public void detachExample(Course course) {
        manager.persist(course);
        maanger.detach(course); 
        // entity is not tracked any more by manager
        // => following update is not happening
        course.setName("new name");
    }

    public void clearExample(Course course) {
        manager.persist(course);
        maanger.clear(); 
        // no entity is tracked by manager
        // => course is not updated
        course.setName("new name");
    }

    public void refreshExample(Course course) {
        manager.persist(course); // course has name "Bla"
        course.setName("new name");
        maanger.refresh(course);
        // refresh loads current representation of course
        // => course will have name "Bla" at this point
    }
}
```

## Hibernate annotations

```java
@Entity
class Course {

    @UpdateTimestamp
    private LocalDateTime lastUpdatedDate;
    
    @CreationTimestamp
    private LocalDateTime createdDate;    

}
```

### Working with dates

[java.sql.Date vs java.util.Date vs java.time.LocalDate](https://vladmihalcea.com/date-timestamp-jpa-hibernate/)

### Named queries

```java
@Entity
@NamedQuery(name="my_query", query="select c from course c")
class Course {

    void theMethod(){ 
        TypedQuery<Course> = 
            EntityManager.createNamedQuery(
                "my_query", 
                Course.class);   
    }
}
```

```java
@Entity
@NamedQueries(value = {
    @NamedQuery(name="my_query", query="select c from course c"),
    @NamedQuery(.....)
})    
class Course {
}
```

### Native queries

```java
@Transactional
@Repository
class SomeRepository {

    @Autowired
    EntityManager manager;
 
    public void theMEthod() {
        manager.createNativeQuery(
            "select * from person",
            Person,class);
    }   
    
    // native queries are useful for massive update
}    
    
```

### Transactional

|                                                    | comment                                                                    |
| -------------------------------------------------- | -------------------------------------------------------------------------- |
| javax @Transactional                               | manage transaction over single DB                                          |
| <p>spring @Transactional</p><p>(isolation=...)</p> | manages transactions over several DBs (if you call many DBs in one method) |

## Spring Data JPA

```java
// you can quickly expose repo as REST using spring-data-rest
@RepositoryRestResource(path="...")
interface MyRepo extend JpaRepository<Course, Long> {

    // provided out of the box
    //Optional<Course> course = findById(Long id);
    // ...
    
    // custom queries
    List<Course> findByName(String name);
    List<Course> findByNameOrderByIdDesc(String name);
    int countByName(String name);
    
    @Query("Select c From Course c where name like 'bla'")
    List<Course> coursesWithBlaName();
}

public class MyUnitTest {

    @Test
    public void testSorting() {
        Sort sort = new Sort(Sort.Direction.DESC, "name");
        myRepo.findAll(sort);
    }

    @Test
    public void testPagination() {
        PageRequest pageRequest = PageRequest.of(0,3);                 
        Page<Course> firstPage = myRepo.findAll(pageRequest);
        
        Pageable secondPageable = firstPage.nextPageable();
        Page<Course> secondPage = myRepo.findAll(secondPageable);
    }
}
```

## Project setup for Spring, Hibernate and Kotlin

[Great article which describes how to setup Hibernate properties for Kotlin case](https://kotlinexpertise.com/hibernate-with-kotlin-spring-boot/)

```kotlin
@MappedSuperclass
abstract class AbstractJpaPersistable<T : Serializable> {

    companion object {
        private val serialVersionUID = -5554308939380869754L
    }

    @Id
    @GeneratedValue
    private var id: T? = null

    fun getId(): T? {
        return id
    }

    @Version
    var version: Int? = null

    @Column(name = "created_at")
    @CreationTimestamp
    var createdAt: LocalDateTime? = null

    @Column(name = "updated_at")
    @UpdateTimestamp
    var updatedAt: LocalDateTime? = null

    override fun equals(other: Any?): Boolean {
        other ?: return false
        if (this === other) return true
        if (javaClass != ProxyUtils.getUserClass(other)) return false
        other as AbstractJpaPersistable<*>
        return if (null == this.getId()) false else this.getId() == other.getId()
    }

    override fun hashCode(): Int {
        return 31
    }

    override fun toString() = "Entity of type ${this.javaClass.name} with id: $id"
}
```

```
//build.gradle.kts
plugins {
...	
	kotlin("plugin.jpa") version "1.6.21"
}

dependencies {
    implementation("org.hibernate:hibernate-core:5.6.12.Final")

    implementation("org.jetbrains.kotlin:kotlin-noarg")
    implementation("org.jetbrains.kotlin:kotlin-allopen")
}

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://amartyushov.gitbook.io/tech/frameworks/spring/jdbc-and-jpa.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
