How can I save collection of value type in hibernate with annotations - List of String List<String> or for example:
#Entity
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
private Set<History> history;
}
and here is value type:
public class History {
private String someAttribute;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((entry == null) ? 0 : entry.hashCode());
result = prime * result + ((entryDate == null) ? 0 : entryDate.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
History other = (History) obj;
if (entry == null) {
if (other.entry != null)
return false;
} else if (!entry.equals(other.entry))
return false;
if (entryDate == null) {
if (other.entryDate != null)
return false;
} else if (!entryDate.equals(other.entryDate))
return false;
return true;
}
}
Can anyone give some example with hibernate annotations?
For an entity to have collection value type, we need to create a separate table to hold this collection as single row of the entity will have multiple values of for this collection. Use #ElementCollection and #CollectionTable annotations on the collection value attribute.
#ElementCollection
#CollectionTable(name = "STUDENT_HISTORY", joinColumns = {#JoinColumn(name = STUDENT_ID) })
#Column(name="HISTORY")
private Set<History> history;
The table will hold the collection values in the column HISTORY and uses STUDENT_ID column as the join column which will be the foreign key to the ID of student.
Below is a complete example using native Hibernate (I mean without the JPA):
Student.java
package domain.app.data;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
#Entity
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#ElementCollection
#CollectionTable(name="STUDENT_HISTORY", joinColumns={#JoinColumn(name="STUDENT_ID", referencedColumnName="ID")})
#Column(name="HISTORY")
private Set<History> history = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<History> getHistory() {
return history;
}
public void setHistory(Set<History> history) {
this.history = history;
}
#Override
public String toString() {
return "Student [id=" + id + ", history=" + history + "]";
}
}
History.java
package domain.app.data;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class History {
#Column(name="HISTORY")
private String someAttribute;
public String getSomeAttribute() {
return someAttribute;
}
public void setSomeAttribute(String someAttribute) {
this.someAttribute = someAttribute;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((someAttribute == null) ? 0 : someAttribute.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
History other = (History) obj;
if (someAttribute == null) {
if (other.someAttribute != null)
return false;
} else if (!someAttribute.equals(other.someAttribute))
return false;
return true;
}
}
HibernateUtil.java
package domain.app.data.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import domain.app.data.Student;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().build();
Configuration configuration = new Configuration();
configuration.addAnnotatedClass(Student.class);
return configuration.buildSessionFactory(serviceRegistry);
}
public static SessionFactory getSession() {
return sessionFactory;
}
}
Application.java
package domain.app;
import org.hibernate.Session;
import domain.app.data.History;
import domain.app.data.Student;
import domain.app.data.util.HibernateUtil;
public class Application {
public static void main(String[] args) {
Session session = HibernateUtil.getSession().openSession();
session.getTransaction().begin();
Student student = new Student();
History history1 = new History();
history1.setSomeAttribute("Volunteer since 2016");
History history2 = new History();
history2.setSomeAttribute("Football team member");
student.getHistory().add(history1);
student.getHistory().add(history2);
session.save(student);
session.getTransaction().commit();
session.close();
}
}
hibernate.properties
hibernate.connection.username=admin
hibernate.connection.password=password
hibernate.connection.url=jdbc:h2:~/h2db/test
hibernate.connection.driver_class=org.h2.Driver
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<configuration debug="false" scan="true" scanPeriod="30 minutes">
<appender name="Console-Appender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%gray(%d{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%5p) %gray(---) %magenta([%15.15t]) %cyan(%-40.40c{1}) %black(:) %m%n%xEx</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="Console-Appender" />
</root>
</configuration>
pom.xml
<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>stackoverflow</groupId>
<artifactId>SO-41248001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.5.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
</project>
Project Structure:
Result in DB:
try this it should work.
#Entity
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#ElementCollection
private Collection Set<History> history;
}
#Embeddable
public class History {
private String someAttribute;
......
}
Related
I keep receiving this error: Error creating bean with name 'entityManagerFactory' (Ive tried every annotation known to man(#ComponentScan, #EnableJPARepositorires #EntityScan) and tried reinstalling/removing jars/versions that may be conflicting. It seems for some reason Spring just cant configure the bean properly any suggestions?
model class:
package com.example.demo.models;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.stereotype.Component;
#Entity
#Table(name="Strain")
#Component
public class Strain {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="strain_id")
private int id;
private String name;
private String StrainType;
private Set<Strain> parents;
public Strain() {
super();
// TODO Auto-generated constructor stub
}
public Strain(int id, String name, String strainType, Set<Strain> parents) {
super();
this.id = id;
this.name = name;
StrainType = strainType;
this.parents = parents;
}
public Strain(String name, String strainType, Set<Strain> parents) {
super();
this.name = name;
StrainType = strainType;
this.parents = parents;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStrainType() {
return StrainType;
}
public void setStrainType(String strainType) {
StrainType = strainType;
}
public Set<Strain> getParents() {
return parents;
}
public void setParents(Set<Strain> parents) {
this.parents = parents;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((StrainType == null) ? 0 : StrainType.hashCode());
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parents == null) ? 0 : parents.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Strain other = (Strain) obj;
if (StrainType == null) {
if (other.StrainType != null)
return false;
} else if (!StrainType.equals(other.StrainType))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (parents == null) {
if (other.parents != null)
return false;
} else if (!parents.equals(other.parents))
return false;
return true;
}
#Override
public String toString() {
return "Strain [id=" + id + ", name=" + name + ", StrainType=" + StrainType + ", parents=" + parents + "]";
}
}
controller:
package com.example.demo.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.models.Strain;
import com.example.demo.services.StrainService;
#RestController
public class StrainController {
#Autowired
private StrainService ss;
#GetMapping(value = "/strains")
#ResponseBody
public List<Strain> findAll() {
return ss.findAll();
}
#GetMapping("/strains/{id}")
#ResponseBody
public ResponseEntity<Strain> findById(#PathVariable("id") int id) {
Strain m = ss.findById(id);
return ResponseEntity.status(HttpStatus.OK).body(m);
}
#PostMapping("/strain")
#ResponseBody
public ResponseEntity<Strain> save(#RequestBody Strain m) {
return ResponseEntity.ok(ss.save(m));
}
#DeleteMapping("/strain")
#ResponseBody
public ResponseEntity<Strain> deleteByName(#RequestBody String name) {
return ResponseEntity.ok(ss.deleteByName(name));
}
}
ServiceClass:
package com.example.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.example.demo.models.Strain;
import com.example.demo.repositories.StrainRepository;
#Service
public class StrainService {
#Autowired
private StrainRepository dao;
public Strain save(Strain s){
return dao.save(s);
}
public void delete(Strain s){
dao.delete(s);
}
public Strain findById(int id) {
return dao.findById(id);
}
public List<Strain> findAll() {
return dao.findAll();
}
public Strain findByName(String name) {
return dao.findByName(name);
}
public int findIdByName(String name) {
return dao.findIdByName(name);
}
public Strain deleteByName(String name) {
return dao.deleteByName(name);
}
public List<Strain> findAllByStrainType(String name){
return dao.findAllByStrainType(name);
}
public boolean existStrainByName(String name) {
return dao.existStrainByName(name);
}
}
repo class:
package com.example.demo.repositories;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.models.Strain;
#Repository
public interface StrainRepository extends JpaRepository<Strain, Integer> {
public Strain save(Strain s);
public void delete(Strain s);
public Strain findById(int id);
public Strain findByName(String name);
public Strain deleteByName(String name);
public List<Strain> findAll();
public List<Strain> findAllByStrainType(String name);
public boolean existStrainByName(String name);
public int findIdByName(String name);
}
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Weedepedia2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Weedepedia2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Alpha5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
it seems to be hibernate related because when i remove the #Entity annotation it goes to another error that has to do with the class not being managed for persistence
In order to get the EntityManagerFactory auto-configured by Spring Boot you need to use spring-boot-starter-data-jpa dependency. In your case, you are using plain spring-data-jpa
Replace
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Alpha5</version>
</dependency>
With
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
And make sure you have the database connection details in your application properties file.
Please see below a snippet of application.yml for PostgreSQL connection
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
Update
Also as #Mohammad Al Alwa pointed out the entity mapping doesn't look good. A typical case would be the entity has a reference to one parent.
In your case that would be
#OneToOne
private Strain parent;
And in the StrainRepository you need to change
public boolean existStrainByName(String name);
To
public boolean existsByName(String name);
Please note you could generate database tables out of your entities if you provide spring.jpa.hibernate.ddl-auto property
Please see below
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: create-only
Hibernate fails to map the entity to a table because you're using a collection field Set<Strain> parents without defining the relationship mapping (ie. #OneToMany or #ManyToMany).
Also, it's not recommended to use a native type int for the id.
i have an issue when attempting to generate table with JBoss EAP 7.2.
My database is named KMT on MS SQL 2014, but when i run the JBoss EAP it creates the table in the system database named "master" despite I specified KMT in my connection-URL.
I created the datasource with the admin console of the JBoss EAP and when testing the connection i got a succes message.
My connection-URL:
JNDI Name: java:/MSSQLDS
Driver Name: sqljdbc42.jar
Connection URL: jdbc:microsoft:sqlserver://localhost:1433;databasename=KMT
My persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="KMT">
<jta-data-source>java:/MSSQLDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
And finally the entity I try to generate inside KMT database:
package be.Alstom.kmt.domaine;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#SuppressWarnings("serial")
#Entity
#Table(name="designer", schema="kmt")
public class Designer implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column
#NotNull
private String userName;
#Column
#NotNull
private String password;
public Designer() {
}
public Designer(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Designer other = (Designer) obj;
if (id != other.id)
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
}
Here the my MSSQL server. Hibernate create table in systemdatabase/master instead of KMT.
I am configuring Hibernate in spring boot - getting below issue. I have added JAXB dependancy and checked so many fixes but it's not working for me.
Please help me to fix.
Configuration
Java version : Java 1.8
DB - MS sql server2012
Spring Boot : 2.1.0.RELEASE
Error :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/hibernate/resource/beans/container/spi/BeanContainer
Application.java
package com.programmer.gate;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.programmer.gate.service.SoccerService;
#SpringBootApplication
public class Application implements CommandLineRunner{
#Autowired
SoccerService soccerService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... arg0) throws Exception {
soccerService.addBarcelonaPlayer("Xavi Hernandez", "Midfielder", 6);
List<String> players = soccerService.getAllTeamPlayers(1);
for(String player : players)
{
System.out.println("Introducing Barca player => " + player);
}
}
}
Application.properties
server.port=9093
# create and drop tables and sequences, loads import.sql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.show-sql=true
# Oracle settings
spring.datasource.url=jdbc:sqlserver://DESKTOP-WIN10:1433;databaseName=employee
spring.datasource.username=emp_db_connect
spring.datasource.password=abi#123
spring.datasource.driver.class=com.microsoft.sqlserver.jdbc.SQLServerDriver
# logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug
#logging.level.org.hibernate.type.descriptor.sql=trace
#logging.level.=debug
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.programmer.gate</groupId>
<artifactId>SpringBootHibernate</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootHibernate</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.3.Final</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
JAVA codes
package com.programmer.gate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
#Entity
public class Player {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "player_Sequence")
#SequenceGenerator(name = "player_Sequence", sequenceName = "PLAYER_SEQ")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "num")
private int num;
#Column(name = "position")
private String position;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "team_id", nullable = false)
private Team team;
public Player() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
}
package com.programmer.gate.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
#Entity
public class Team {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "team_Sequence")
#SequenceGenerator(name = "team_Sequence", sequenceName = "TEAM_SEQ")
private Long id;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
mappedBy = "team")
private List<Player> players;
public Team() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Player> getPlayers() {
return players;
}
}
package com.programmer.gate.repository;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.programmer.gate.model.Player;
#Repository
public interface PlayerRepository extends CrudRepository<Player, Long> {
List<Player> findByTeamId(long teamId);
}
package com.programmer.gate.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.programmer.gate.model.Team;
#Repository
public interface TeamRepository extends CrudRepository<Team, Long> {
Team findByPlayers(long playerId);
}
package com.programmer.gate.service;
import java.util.List;
public interface SoccerService {
public List<String> getAllTeamPlayers(long teamId);
public void addBarcelonaPlayer(String name, String position, int number);
}
package com.programmer.gate.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.programmer.gate.model.Player;
import com.programmer.gate.model.Team;
import com.programmer.gate.repository.PlayerRepository;
import com.programmer.gate.repository.TeamRepository;
#Service
public class SoccerServiceImpl implements SoccerService {
#Autowired
private PlayerRepository playerRepository;
#Autowired
private TeamRepository teamRepository;
public List<String> getAllTeamPlayers(long teamId) {
List<String> result = new ArrayList<String>();
List<Player> players = playerRepository.findByTeamId(teamId);
for (Player player : players) {
result.add(player.getName());
}
return result;
}
public void addBarcelonaPlayer(String name, String position, int number) {
//
Team barcelona = teamRepository.findOne(1l);
Player newPlayer = new Player();
newPlayer.setName(name);
newPlayer.setPosition(position);
newPlayer.setNum(number);
newPlayer.setTeam(barcelona);
playerRepository.save(newPlayer);
}
}
I'm new to hibernate and as I researched. When i want to start my JUnit, this mistake could be occur every time. I guess something wrong with my hbm.xml file. Maybe I am missing something because I'm still new to hibernate.
This is my hbm.xml file.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.UserEntity" table="user" schema="" catalog="junwa">
<id name="id" column="id"/>
<property name="username" column="username"/>
<property name="gender" column="gender"/>
<property name="birthday" column="birthday"/>
<property name="addres" column="addres"/>
</class>
</hibernate-mapping>
And this is my UserEntity.java file
package com.test;
import javax.persistence.*;
import java.sql.Timestamp;
#Entity
#Table(name = "user", schema = "", catalog = "junwa")
public class UserEntity {
private int id;
private String username;
private String gender;
private Timestamp birthday;
private String addres;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Basic
#Column(name = "gender")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Basic
#Column(name = "birthday")
public Timestamp getBirthday() {
return birthday;
}
public void setBirthday(Timestamp birthday) {
this.birthday = birthday;
}
#Basic
#Column(name = "addres")
public String getAddres() {
return addres;
}
public void setAddres(String addres) {
this.addres = addres;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (id != that.id) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (gender != null ? !gender.equals(that.gender) : that.gender != null) return false;
if (birthday != null ? !birthday.equals(that.birthday) : that.birthday != null) return false;
if (addres != null ? !addres.equals(that.addres) : that.addres != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (gender != null ? gender.hashCode() : 0);
result = 31 * result + (birthday != null ? birthday.hashCode() : 0);
result = 31 * result + (addres != null ? addres.hashCode() : 0);
return result;
}
}
This is my test file.
/**
* Created by junwa on 2017/4/2.
*/
import com.test.Students;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
public class StudentsTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
#Before
public void init(){
// create a deploy object
Configuration config = new Configuration().configure();
// create a service licenced object
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// create a session factory object
sessionFactory = config.buildSessionFactory(serviceRegistry);
// create a sessoin object
session = sessionFactory.openSession();
// start transaction
transaction = session.beginTransaction();
}
#After
public void destroy(){
// commit transaction
transaction.commit();
// close session
session.close();
// close session factory
sessionFactory.close();
}
#Test
public void testSaveStudents(){
// create a object
Students s = new Students(1,"junwa","male",new Date(),"Anhui");
// save object to mysql database
session.save(s);
session.flush();
}
}
This my output
enter image description here
As Faraz Durrani said when you already have done the mapping in hbm.xml file, why do you need annotations for? Or the vice versa.You have to remove one of them. I would say remove hbm.xml file and use Annotations only.
One more thing I have noticed that you are not closing the transection also.
You can't use hbm.xml and annotation at the same time.
This issue is a continuation of this problem: Foreign key as a part of composite primary key and ManyToOne relationship in OpenJPA
OpenJPA is tring to cast my entity class (TableB) to type of its key (long). Why?
Persisting of TableB object without any elements in field rows works fine. The problem begins when 'm adding elements to rows.
TableA.class:
package org.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
#IdClass(TableA_PK.class)
public class TableA implements Serializable {
#Id
private int fId;
#Id
private String item;
#Id
private String release;
#Id
#ManyToOne
#JoinColumn(name = "b_id")
private TableB tableB;
#Column
private String field1;
#Column
private String field2;
public TableA() {
}
public int getfId() {
return fId;
}
public void setfId(int fId) {
this.fId = fId;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getRelease() {
return release;
}
public void setRelease(String release) {
this.release = release;
}
public TableB getTableB() {
return tableB;
}
public void setTableB(TableB tableB) {
this.tableB = tableB;
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
}
TableA_PK.class:
package org.model;
import java.io.Serializable;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class TableA_PK implements Serializable {
private int fId;
private String item;
private String release;
private long tableB;
public TableA_PK() {
}
public int getfId() {
return fId;
}
public void setfId(int fId) {
this.fId = fId;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getRelease() {
return release;
}
public void setRelease(String release) {
this.release = release;
}
public long getTableB() {
return tableB;
}
public void setTableB(long tableB) {
this.tableB = tableB;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
TableA_PK rhs = (TableA_PK) obj;
return new EqualsBuilder().append(fId, rhs.fId).append(item, rhs.item)
.append(release, rhs.release).append(tableB, rhs.tableB)
.isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder().append(fId).append(item).append(release)
.append(tableB).toHashCode();
}
}
TableB.class:
package org.model;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
#Entity
public class TableB implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column
private String name;
#Column
private Date date;
#OneToMany(mappedBy = "tableB", cascade = CascadeType.PERSIST)
private List<TableA> rows;
public TableB() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public List<TableA> getRows() {
return rows;
}
public void setRows(List<TableA> rows) {
this.rows = rows;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
TableB rhs = (TableB) obj;
return new EqualsBuilder().append(id, rhs.id).append(name, rhs.name)
.append(date, rhs.date).isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder().append(id).append(name).append(date)
.toHashCode();
}
}
JpaTest.class:
package org.model;
import java.util.ArrayList;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.junit.Test;
public class JpaTest {
#Test
public void test() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("rd-jpa");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction userTransaction = em.getTransaction();
userTransaction.begin();//BEGIN TRANSACTION 1.
TableB tableb = new TableB();
tableb.setDate(new Date());
tableb.setName("tableb2");
em.persist(tableb); // fills tableb id
userTransaction.commit(); //COMMIT 1
userTransaction = em.getTransaction();
userTransaction.begin();//BEGIN TRANSACTION 2.
TableA tableA = new TableA();
tableA.setfId(665);
tableA.setField1("field1");
tableA.setField2("field2");
tableA.setItem("item2");
tableA.setRelease("1");
tableA.setTableB(tableb);
ArrayList<TableA> rows = new ArrayList<TableA>();
rows.add(tableA);
tableb.setRows(rows);
em.persist(tableb);
userTransaction.commit();
em.clear();
em.close();
}
}
Stack Trace after running JpaTest:
<openjpa-2.3.0-r422266:1540826 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: org.model.TableB cannot be cast to java.lang.Number
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2526)
at org.apache.openjpa.kernel.SingleFieldManager.persist(SingleFieldManager.java:279)
at org.apache.openjpa.kernel.StateManagerImpl.cascadePersist(StateManagerImpl.java:3081)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2648)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2604)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2587)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2491)
at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1077)
at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:716)
at org.model.JpaTest.test(JpaTest.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number
at org.apache.openjpa.util.ApplicationIds$PrimaryKeyFieldManager.fetchLongField(ApplicationIds.java:669)
at org.apache.openjpa.enhance.org$model$TableA$pcsubclass.pcCopyKeyFieldsToObjectId(Unknown Source)
at org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:169)
at org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:224)
at org.apache.openjpa.enhance.ReflectingPersistenceCapable.pcNewObjectIdInstance(ReflectingPersistenceCapable.java:277)
at org.apache.openjpa.util.ApplicationIds.create(ApplicationIds.java:427)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2675)
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2521)
... 32 more
persistence.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="rd-jpa" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.model.TableA</class>
<class>org.model.TableB</class>
<properties>
<property name="openjpa.ConnectionURL"
value="jdbc:postgresql://localhost:5432/mydb" />
<property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver" />
<property name="openjpa.ConnectionUserName" value="postgres" />
<property name="openjpa.ConnectionPassword" value="postgres" />
<property name="openjpa.DynamicEnhancementAgent" value="true" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
</properties>
</persistence-unit>
</persistence>
pom.xml:
<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>jpa</groupId>
<artifactId>jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source />
<target />
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-maven-plugin</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
Try to get rid of the openjpa.RuntimeUnenhancedClasses property and enhance your Entities properly.