diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml
index cae8a725a6..90b1f6bb1d 100644
--- a/libraries-data/pom.xml
+++ b/libraries-data/pom.xml
@@ -36,6 +36,11 @@
reladomo-test-util
${reladomo.version}
+
+ com.j256.ormlite
+ ormlite-jdbc
+ ${ormlite.version}
+
@@ -144,5 +149,6 @@
16.5.1
4.12
3.6.2
+ 5.0
\ No newline at end of file
diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Address.java b/libraries-data/src/main/java/com/baeldung/ormlite/Address.java
new file mode 100644
index 0000000000..747b0b0b12
--- /dev/null
+++ b/libraries-data/src/main/java/com/baeldung/ormlite/Address.java
@@ -0,0 +1,37 @@
+package com.baeldung.ormlite;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+@DatabaseTable(tableName = "addresses")
+public class Address {
+ @DatabaseField(generatedId = true)
+ private long addressId;
+
+ @DatabaseField(canBeNull = false)
+ private String addressLine;
+
+ public Address() {
+ }
+
+ public Address(String addressLine) {
+ this.addressLine = addressLine;
+ }
+
+ public long getAddressId() {
+ return addressId;
+ }
+
+ public void setAddressId(long addressId) {
+ this.addressId = addressId;
+ }
+
+ public String getAddressLine() {
+ return addressLine;
+ }
+
+ public void setAddressLine(String addressLine) {
+ this.addressLine = addressLine;
+ }
+
+}
diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Book.java b/libraries-data/src/main/java/com/baeldung/ormlite/Book.java
new file mode 100644
index 0000000000..ed7b813b8d
--- /dev/null
+++ b/libraries-data/src/main/java/com/baeldung/ormlite/Book.java
@@ -0,0 +1,49 @@
+package com.baeldung.ormlite;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+@DatabaseTable
+public class Book {
+
+ @DatabaseField(generatedId = true)
+ private long bookId;
+
+ @DatabaseField
+ private String title;
+
+ @DatabaseField(foreign = true, foreignAutoRefresh = true, foreignAutoCreate = true)
+ private Library library;
+
+ public Book() {
+ }
+
+ public Book(String title) {
+ this.title = title;
+ }
+
+ public long getBookId() {
+ return bookId;
+ }
+
+ public void setBookId(long bookId) {
+ this.bookId = bookId;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Library getLibrary() {
+ return library;
+ }
+
+ public void setLibrary(Library library) {
+ this.library = library;
+ }
+
+}
diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Library.java b/libraries-data/src/main/java/com/baeldung/ormlite/Library.java
new file mode 100644
index 0000000000..994b4c6575
--- /dev/null
+++ b/libraries-data/src/main/java/com/baeldung/ormlite/Library.java
@@ -0,0 +1,58 @@
+package com.baeldung.ormlite;
+
+import com.j256.ormlite.dao.ForeignCollection;
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.field.ForeignCollectionField;
+import com.j256.ormlite.table.DatabaseTable;
+
+@DatabaseTable(tableName = "libraries", daoClass = LibraryDaoImpl.class)
+public class Library {
+
+ @DatabaseField(generatedId = true)
+ private long libraryId;
+
+ @DatabaseField(canBeNull = false)
+ private String name;
+
+ @DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true)
+ private Address address;
+
+ @ForeignCollectionField(eager = false)
+ private ForeignCollection books;
+
+ public Library() {
+ }
+
+ public long getLibraryId() {
+ return libraryId;
+ }
+
+ public void setLibraryId(long libraryId) {
+ this.libraryId = libraryId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public ForeignCollection getBooks() {
+ return books;
+ }
+
+ public void setBooks(ForeignCollection books) {
+ this.books = books;
+ }
+
+}
diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java
new file mode 100644
index 0000000000..fd8f5f40d6
--- /dev/null
+++ b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java
@@ -0,0 +1,10 @@
+package com.baeldung.ormlite;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import com.j256.ormlite.dao.Dao;
+
+public interface LibraryDao extends Dao {
+ public List findByName(String name) throws SQLException;
+}
diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java
new file mode 100644
index 0000000000..af313101e2
--- /dev/null
+++ b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java
@@ -0,0 +1,21 @@
+package com.baeldung.ormlite;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import com.j256.ormlite.dao.BaseDaoImpl;
+import com.j256.ormlite.support.ConnectionSource;
+
+public class LibraryDaoImpl extends BaseDaoImpl implements LibraryDao {
+
+ public LibraryDaoImpl(ConnectionSource connectionSource) throws SQLException {
+ super(connectionSource, Library.class);
+ }
+
+ @Override
+ public List findByName(String name) throws SQLException {
+ return super.queryForEq("name", name);
+
+ }
+
+}
diff --git a/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteTest.java b/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteTest.java
new file mode 100644
index 0000000000..eaa21b6eaf
--- /dev/null
+++ b/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteTest.java
@@ -0,0 +1,171 @@
+package com.baeldung.ormlite;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import com.j256.ormlite.dao.CloseableWrappedIterable;
+import com.j256.ormlite.dao.Dao;
+import com.j256.ormlite.dao.DaoManager;
+import com.j256.ormlite.jdbc.JdbcPooledConnectionSource;
+import com.j256.ormlite.table.TableUtils;
+
+public class ORMLiteTest {
+ private static JdbcPooledConnectionSource connectionSource;
+
+ private static Dao libraryDao;
+ private static Dao bookDao;
+
+ @BeforeClass
+ public static void setup() throws SQLException {
+ connectionSource = new JdbcPooledConnectionSource("jdbc:h2:mem:myDb");
+ TableUtils.createTableIfNotExists(connectionSource, Library.class);
+ TableUtils.createTableIfNotExists(connectionSource, Address.class);
+ TableUtils.createTableIfNotExists(connectionSource, Book.class);
+
+ libraryDao = DaoManager.createDao(connectionSource, Library.class);
+
+ bookDao = DaoManager.createDao(connectionSource, Book.class);
+ }
+
+ @Test
+ public void givenDAO_whenCRUD_thenOk() throws SQLException {
+ Library library = new Library();
+ library.setName("My Library");
+ libraryDao.create(library);
+
+ Library result = libraryDao.queryForId(library.getLibraryId());
+ assertEquals("My Library", result.getName());
+
+ library.setName("My Other Library");
+ libraryDao.update(library);
+
+ libraryDao.delete(library);
+
+ }
+
+ @Test
+ public void whenLoopDao_thenOk() throws SQLException {
+ Library library1 = new Library();
+ library1.setName("My Library");
+ libraryDao.create(library1);
+
+ Library library2 = new Library();
+ library2.setName("My Other Library");
+ libraryDao.create(library2);
+
+ libraryDao.forEach(lib -> {
+ System.out.println(lib.getName());
+ });
+
+ }
+
+ @Test
+ public void givenIterator_whenLoop_thenOk() throws SQLException, IOException {
+ Library library1 = new Library();
+ library1.setName("My Library");
+ libraryDao.create(library1);
+
+ Library library2 = new Library();
+ library2.setName("My Other Library");
+ libraryDao.create(library2);
+
+ CloseableWrappedIterable wrappedIterable = libraryDao.getWrappedIterable();
+ try {
+ wrappedIterable.forEach(lib -> {
+ System.out.println(lib.getName());
+ });
+ } finally {
+ wrappedIterable.close();
+ }
+
+ }
+
+ @Test
+ public void givenCustomDao_whenSave_thenOk() throws SQLException, IOException {
+ Library library = new Library();
+ library.setName("My Library");
+
+ LibraryDao customLibraryDao = DaoManager.createDao(connectionSource, Library.class);
+ customLibraryDao.create(library);
+ assertEquals(1, customLibraryDao.findByName("My Library")
+ .size());
+ }
+
+ @Test
+ public void whenSaveForeignField_thenOk() throws SQLException, IOException {
+ Library library = new Library();
+ library.setName("My Library");
+ library.setAddress(new Address("Main Street nr 20"));
+ libraryDao.create(library);
+
+ Dao addressDao = DaoManager.createDao(connectionSource, Address.class);
+ assertEquals(1, addressDao.queryForEq("addressLine", "Main Street nr 20")
+ .size());
+ }
+
+ @Test
+ public void whenSaveForeignCollection_thenOk() throws SQLException, IOException {
+ Library library = new Library();
+ library.setName("My Library");
+ libraryDao.create(library);
+ libraryDao.refresh(library);
+ library.getBooks()
+ .add(new Book("1984"));
+
+ Book book = new Book("It");
+ book.setLibrary(library);
+ bookDao.create(book);
+
+ assertEquals(2, bookDao.queryForEq("library_id", library)
+ .size());
+ }
+
+ @Test
+ public void whenGetLibrariesWithMoreThanOneBook_thenOk() throws SQLException, IOException {
+ Library library = new Library();
+ library.setName("My Library");
+ libraryDao.create(library);
+ Library library2 = new Library();
+ library2.setName("My Other Library");
+ libraryDao.create(library2);
+
+ libraryDao.refresh(library);
+ libraryDao.refresh(library2);
+
+ library.getBooks()
+ .add(new Book("Book1"));
+ library2.getBooks()
+ .add(new Book("Book2"));
+ library2.getBooks()
+ .add(new Book("Book3"));
+
+ List libraries = libraryDao.queryBuilder()
+ .where()
+ .in("libraryId", bookDao.queryBuilder()
+ .selectColumns("library_id")
+ .groupBy("library_id")
+ .having("count(*) > 1"))
+ .query();
+ assertEquals(1, libraries.size());
+
+ }
+
+ @After
+ public void clear() throws SQLException {
+ TableUtils.clearTable(connectionSource, Library.class);
+ TableUtils.clearTable(connectionSource, Book.class);
+ TableUtils.clearTable(connectionSource, Address.class);
+ }
+
+ @AfterClass
+ public static void tearDown() throws SQLException, IOException {
+ connectionSource.close();
+ }
+}