`Task:
- Create a connection to your database and a schema. Launch the application. Check that it is fully working.
- Create a Car entity with the String model and int series fields, which will be referenced by the User using a one-to-one relationship.
- Add this class to the hibernate settings.
- Create several users with machines, add them to the database, pull them back.
- Add a method to the service that will use an hql query to get a user who owns a machine by its model and series.
The problem is that the code that works for a friend of mine works for half
public static void main(String[] args) throws SQLException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
User user1 = new User("User1", "Lastname1", "user1@mail.ru");
Car cfr1 = new Car("Mersedes", 1);
user1.setCar(cfr1);
userService.add(user1);
User user11 = new User("User2", "Lastname2", "user22@mail.ru");
Car cfr11 = new Car("BMW", 3);
user11.setCar(cfr11);
userService.add(user11);
List<User> users = userService.listUsers();
for (User user : users) {
System.out.println("Id = " + user.getId());
System.out.println("First Name = " + user.getFirstName());
System.out.println("Last Name = " + user.getLastName());
System.out.println("Email = " + user.getEmail());
System.out.println("Car = " + user.getCar());
System.out.println();
}
User user111 = userService.getUserByCar("BMW", 3);
System.out.println("Владелец машины по модели и серии - " + user111);
context.close();
}
this is main
this is the db.properties file
# MySQL properties
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=12345
# Hibernate properties
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
this is an exception
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect Hibernate: alter table cars add constraint FKqw4c8e6nqrvy3ti1xj8w8wyc9 foreign key (user_id) references users (id) апр. 04, 2023 12:34:17 AM org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException WARN: GenerationTarget encountered exception accepting command : Error executing DDL "alter table cars add constraint FKqw4c8e6nqrvy3ti1xj8w8wyc9 foreign key (user_id) references users (id)" via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table cars add constraint FKqw4c8e6nqrvy3ti1xj8w8wyc9 foreign key (user_id) references users (id)" via JDBC Statement
appConfig
package hiber.config;
import hiber.model.Car;
import hiber.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScan(value = "hiber")
public class AppConfig {
@Autowired
private Environment env;
@Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
dataSource.setUsername(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
return dataSource;
}
@Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(getDataSource());
Properties props = new Properties();
props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
factoryBean.setHibernateProperties(props);
factoryBean.setAnnotatedClasses(User.class, Car.class);
return factoryBean;
}
@Bean
public HibernateTransactionManager getTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(getSessionFactory().getObject());
return transactionManager;
}
}
car class
package hiber.model;
import javax.persistence.*;
@Entity
@Table(name = "cars")
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "model")
private String model;
@Column(name = "series")
private int series;
@OneToOne
@JoinColumn(name = "user_id",referencedColumnName = "id")
private User user;
public Car(){
}
public Car(String model, int series) {
this.model = model;
this.series = series;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public int getSeries() {
return series;
}
public void setSeries(int series) {
this.series = series;
}
public User getUser() {
return user;
}
public User setUser(User user) {
this.user = user;
return user;
}
@Override
public String toString() {
return "Car {" +
"id=" + id +
", model='" + model + '\'' +
", series=" + series +
'}';
}
}
class user
package hiber.model;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@OneToOne(mappedBy = "user")
private Car car;
public User() {}
public User(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Car getCar(){return car;}
public Car setCar(Car car){
this.car =car;
return car;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
using debug, I found out that the exception flies to:
User userThree = userService.getUserByCar("Mers", 2019);
class UserServiceImp:
@Service
public class UserServiceImp implements UserService {
@Autowired
private UserDao userDao;
@Transactional
@Override
public void add(User user) {
userDao.add(user);
}
@Transactional(readOnly = true)
@Override
public List<User> listUsers() {
return userDao.listUsers();
}
public User getUserByCar(String model, int series){
return userDao.getUserByCar(model,series);
}
}
class UserDaoImp:
@Repository
public class UserDaoImp implements UserDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public void add(User user) {
sessionFactory.getCurrentSession().save(user);
}
@Override
@SuppressWarnings("unchecked")
public List<User> listUsers() {
TypedQuery<User> query = sessionFactory.getCurrentSession().createQuery("from User");
return query.getResultList();
}
@Override
@SuppressWarnings("unchecked")
public User getUserByCar(String model, int series) {
String hql = "from User user where user.car.model = :model and user.car.series = :series";
TypedQuery<User> query = sessionFactory.getCurrentSession().createQuery(hql);
query.setParameter("model", model).setParameter("series", series);
return query.getSingleResult();
}
}