diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fb23144f9f0f97990924023d0fd851e6c46d2e5f --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +# Project-specific +# none (for now) + +# Mac file finder metadata +.DS_Store +# Emacs backup file +*~ + +# Java files +*.class +javadoc/ + +# IntelliJ IDEA files +.idea/ +out/ +*.iml +*.iws +*.ipr + +# Eclipse files +bin/ +.settings/ +.classpath +.project + +# Visual Studio / VS Code files +.vs*/ +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Netbeans files +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml + +# Xcode files +*.xcodeproj/ +xcuserdata/ +.build/ + +# Maven +target/ + +# Miscellaneous +tmp/ +*.bak +*.bk +*.swp +*.gcno + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..3904a28c7f61fb00f1902dbfb25ea9b9f6d1e051 --- /dev/null +++ b/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>edu.unl.cse.csce361</groupId> + <artifactId>hibernate-example</artifactId> + <version>1.0-SNAPSHOT</version> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.1</version> + <configuration> + <source>8</source> + <target>8</target> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + + <!-- FOR PRODUCTION CODE --> + + <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <version>5.4.12.Final</version> + </dependency> + <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>8.0.19</version> + </dependency> + + <!-- FOR TEST CODE --> + + <!-- https://mvnrepository.com/artifact/junit/junit --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13</version> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/org.hsqldb/hsqldb --> + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>2.5.0</version> + <scope>test</scope> + </dependency> + + </dependencies> + +</project> diff --git a/src/main/java/edu/unl/cse/csce361/hibernate/Fruit.java b/src/main/java/edu/unl/cse/csce361/hibernate/Fruit.java new file mode 100644 index 0000000000000000000000000000000000000000..0fe545a963e0d1802b9f75fdc222df8081ae0f5c --- /dev/null +++ b/src/main/java/edu/unl/cse/csce361/hibernate/Fruit.java @@ -0,0 +1,83 @@ +package edu.unl.cse.csce361.hibernate; + +import javax.persistence.*; + +@SuppressWarnings("unused") +@Entity +public class Fruit { + @Id + @GeneratedValue + private Integer id; + + @Column + private String fruitType; + + @Column + private String color; + + @Column + private Integer massInGrams; + + @ManyToOne + @JoinColumn(name = "fruitSalad") + private FruitSalad salad; + + public Fruit() { // 0-argument constructor + } + + public Fruit(String fruitType, String color) { // convenience constructor + setFruitType(fruitType); + setColor(color); + } + + public Fruit(String fruitType, String color, int massInGrams) { // convenience constructor + setFruitType(fruitType); + setColor(color); + setMassInGrams(massInGrams); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getFruitType() { + return fruitType; + } + + public void setFruitType(String fruitType) { + this.fruitType = fruitType; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public Integer getMassInGrams() { + return massInGrams; + } + + public void setMassInGrams(Integer massInGrams) { + this.massInGrams = massInGrams; + } + + public FruitSalad getSalad() { + return salad; + } + + public void setSalad(FruitSalad salad) { + this.salad = salad; + } + + @Override + public String toString() { + return getMassInGrams() + "g of " + getFruitType(); + } +} diff --git a/src/main/java/edu/unl/cse/csce361/hibernate/FruitPopulator.java b/src/main/java/edu/unl/cse/csce361/hibernate/FruitPopulator.java new file mode 100644 index 0000000000000000000000000000000000000000..dfb003d7c03013d57f62e1a13deeebf3d85b62ef --- /dev/null +++ b/src/main/java/edu/unl/cse/csce361/hibernate/FruitPopulator.java @@ -0,0 +1,76 @@ +package edu.unl.cse.csce361.hibernate; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +public class FruitPopulator { + private static Session session = null; + + public static Session getSession() { + if (session == null) { + SessionFactory sessionFactory = null; + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build(); + try { + sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); + } catch (Exception exception) { + // sessionFactory didn't have the opportunity to destroy serviceRegistry like it should've + StandardServiceRegistryBuilder.destroy(serviceRegistry); + System.err.println("Failed to create session. " + exception); + System.exit(1); + } + session = sessionFactory.openSession(); + } + return session; + } + + public static void closeSession(Session session) { + session.close(); + //noinspection UnusedAssignment + session = null; + } + + private void makeFruitSalad() { + Session session = getSession(); + try { + session.beginTransaction(); + Fruit apple = new Fruit("apple", "red", 80); + Fruit banana = new Fruit("banana", "yellow", 27); + Fruit orange = new Fruit("orange", "orange"); + session.save(apple); + session.save(banana); + session.save(orange); + FruitSalad fruitSalad = new FruitSalad(); + fruitSalad.setRecipeName("Simple Fruit Salad"); + session.save(fruitSalad); + fruitSalad.addFruit(apple); + fruitSalad.addFruit(banana); + session.getTransaction().commit(); + System.out.println("Successfully populated tables."); + } catch (RuntimeException exception) { + session.getTransaction().rollback(); + System.out.println("Failed to populate tables. " + exception); + } + } + + private void examineFruitSalad() { + Session session = getSession(); + session.beginTransaction(); + FruitSalad fruitSalad = session.load(FruitSalad.class, 4); // This is INCREDIBLY fragile + session.getTransaction().commit(); + System.out.print(fruitSalad + " contains "); + for(Fruit fruit: fruitSalad.getFruits()) { + System.out.print(fruit + " and "); + } + System.out.println("that is all."); + } + + public static void main(String[] args) { + FruitPopulator fruitPopulator = new FruitPopulator(); + fruitPopulator.makeFruitSalad(); + fruitPopulator.examineFruitSalad(); + closeSession(session); + } +} diff --git a/src/main/java/edu/unl/cse/csce361/hibernate/FruitSalad.java b/src/main/java/edu/unl/cse/csce361/hibernate/FruitSalad.java new file mode 100644 index 0000000000000000000000000000000000000000..e138835327589ae629407188bb16102d5fa889e3 --- /dev/null +++ b/src/main/java/edu/unl/cse/csce361/hibernate/FruitSalad.java @@ -0,0 +1,53 @@ +package edu.unl.cse.csce361.hibernate; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@SuppressWarnings("unused") +@Entity +public class FruitSalad { + @Id + @GeneratedValue + private Integer id; + + @Column + private String recipeName; + + @OneToMany(mappedBy= "salad") + private Set<Fruit> fruits = new HashSet<>(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getRecipeName() { + return recipeName; + } + + public void setRecipeName(String recipeName) { + this.recipeName = recipeName; + } + + public Set<Fruit> getFruits() { + return fruits; + } + + public void setFruits(Set<Fruit> fruits) { + this.fruits = fruits; + } + + public void addFruit(Fruit fruit) { + fruits.add(fruit); + fruit.setSalad(this); + } + + @Override + public String toString() { + return getRecipeName(); + } +} diff --git a/src/main/resources/.gitignore b/src/main/resources/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..004118f8e741c116ea2ce35f2cf4fe267249aaa7 --- /dev/null +++ b/src/main/resources/.gitignore @@ -0,0 +1,2 @@ +hibernate.cfg.xml + diff --git a/src/main/resources/hibernate.cfg.xml-TEMPLATE b/src/main/resources/hibernate.cfg.xml-TEMPLATE new file mode 100644 index 0000000000000000000000000000000000000000..69ab20efc3b81174d9298a5ac134664c6b3d0dda --- /dev/null +++ b/src/main/resources/hibernate.cfg.xml-TEMPLATE @@ -0,0 +1,37 @@ +<!DOCTYPE hibernate-configuration PUBLIC + "-//Hibernate/Hibernate Configuration DTD 3.0//EN" + "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> + +<hibernate-configuration> + <session-factory> + <property name="dialect"> + org.hibernate.dialect.MySQL5Dialect + </property> + <property name="connection.driver_class"> + com.mysql.jdbc.Driver + </property> + <property name="connection.url"> + jdbc:mysql://cse.unl.edu/USERNAME + </property> + <property name="connection.username"> + USERNAME + </property> + <property name="connection.password"> + MYSQL_PASSWORD + </property> + + <!-- Echo all executed SQL to stdout --> + <property name="show_sql"> + true + </property> + + <!-- Drop and re-create the database schema on startup --> + <property name="hbm2ddl.auto"> + create + </property> + + <!-- Names the annotated entity class --> + <mapping class="edu.unl.cse.csce361.hibernate.Fruit"/> + + </session-factory> +</hibernate-configuration>