Supposing I have entity Lecturer and Course two entities having many to many relationships in JPA 2.0
It is perfectly OK to have a non-annotated entity LecturerCourse (with multi-table selection columns, not annotated) and JPQL like this working.
final Query query = em.createQuery(
"select new com.cs.entity.LectureCourse(l.id, l.name, l.surName, " +
"l.type, c.code, c.name) from lecturer l join l.courses c where l.id = :l_id"
);
How can I do the same with JPA Criteria API?
Here are the code for Lecturer and Courses respectively
#Entity(name = "course")
public class Course implements Serializable {
#Id
#Column(name = "course_code", columnDefinition = "char(6)",
unique = true, nullable = false)
private String code;
#Column(name = "course_name")
private String name;
#ManyToMany(mappedBy = "courseSet", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Student> students;
#ManyToOne(fetch = FetchType.EAGER, targetEntity = Lecturer.class)
#JoinColumn(name = "lecture_id")
private Lecturer lecturer;
public Course() {
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public Lecturer getLecturer() {
return lecturer;
}
public void setLecturer(Lecturer lecturer) {
this.lecturer = lecturer;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Course)) return false;
Course course = (Course) o;
if (code != null ? !code.equals(course.code) : course.code != null) return false;
if (name != null ? !name.equals(course.name) : course.name != null) return false;
if (students != null ? !students.equals(course.students) : course.students != null) return false;
return true;
}
#Override
public int hashCode() {
int result = code != null ? code.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (students != null ? students.hashCode() : 0);
return result;
}
}
#Entity(name = "lecturer")
public class Lecturer {
public static enum LectureType{
FULL_TIME, PART_TIME
}
#Id
#Column(name = "lecture_id", nullable = false,
unique = true, columnDefinition = "char(8)")
private String id;
#Column(name = "lecture_name", length = 20, nullable = false)
private String name;
#Column(name = "lecture_sur_name", length = 20, nullable = false)
private String surName;
#Enumerated(EnumType.ORDINAL)
#Column(name = "lecture_type", columnDefinition = "char(1)")
private LectureType type;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "lecturer", fetch = FetchType.EAGER)
private Set<Course> courses;
public Lecturer() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public LectureType getType() {
return type;
}
public void setType(LectureType type) {
this.type = type;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
for(final Course course : this.courses){
course.setLecturer(this);
}
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Lecturer)) return false;
Lecturer lecturer = (Lecturer) o;
if (id != null ? !id.equals(lecturer.id) : lecturer.id != null) return false;
if (name != null ? !name.equals(lecturer.name) : lecturer.name != null) return false;
if (surName != null ? !surName.equals(lecturer.surName) : lecturer.surName != null) return false;
if (type != lecturer.type) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (surName != null ? surName.hashCode() : 0);
result = 31 * result + (type != null ? type.hashCode() : 0);
return result;
}
}
What you're looking for is a form of CriteriaQuery#multiselect ... I'm assuming you're generating an appropriate static metamodel (that's where the EntityClass_.field pieces come from) but working by hand I come up with something like:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<LectureCourse> criteria = builder.createQuery(LectureCourse.class);
Root<Lecturer> l = criteria.from(Lecturer.class);
Path<Course> c = l.join(Lecturer_.courses);
ParameterExpression<String> l_id = builder.parameter(String.class);
Predicate lecturerIdMatches = builder.equal(l.get(Lecturer_.id),l_id);
TypedQuery<LectureCourse> query = em.createQuery(criteria.multiselect(l.get(Lecturer_.id), l.get(Lecturer_.name), l.get(Lecturer_.surName), l.get(Lecturer_.type), c.get(Course_.code), c.get(Course_.name)).where(lecturerIdMatches));
query.setParameter(l_id,"queryvalue");
List<LectureCourse> results = query.getResultList();
Related
I want to manage Persons, Teams and their Membership with Spring Data JPA.
The following test (whenAddingANewTeamTroughPerson)
passes when I use entityManager.persist(alex);
throws an exception if I use personRepository.save(alex);
Why? In the latter case I get the following exception:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: hello.data.model.Person; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: hello.data.model.Person
It behaves as CASCADE is not set properely. But it must be correct, since it works with the entityManager.
PersonRepositoryTest:
#RunWith(SpringRunner.class)
#DataJpaTest
public class PersonRepositoryTest {
#Autowired
private TestEntityManager entityManager;
#Autowired
private PersonRepository personRepository;
#Autowired
private TeamRepository teamRepository;
#Test
public void whenFindOne_thenReturnPerson() {
// given
Person alex = new Person("alex");
entityManager.persist(alex);
entityManager.flush();
// when
Person found = personRepository.findOne(alex.getId());
// then
assertThat(found.getName(), equalToIgnoringWhiteSpace(alex.getName()));
}
#Test
public void whenAddingANewTeamTroughPerson_thenNoException() {
// given
Person alex = new Person("alex");
Team t = new Team("team");
alex.addTeam(t, "integrationTest", new Date());
personRepository.save(alex);
//entityManager.persist(alex);
// when
Person found = personRepository.findOne(alex.getId());
// then
assertThat(found.getTeams().size(), is(1));
}
}
PersonRepository:
public interface PersonRepository extends CrudRepository<Person, Integer> {}
Person:
#Entity
public class Person {
private static final Logger LOG = LoggerFactory.getLogger(Person.class);
private final IntegerProperty id = new SimpleIntegerProperty(this, "id");
private final StringProperty name = new SimpleStringProperty(this, "name");
private Set<PersonTeam> personTeams = new LinkedHashSet<>();
private ListProperty<Team> teams = new SimpleListProperty<>(this, "teams", FXCollections.observableArrayList());
public Person(String s) {
this.name.set(s);
}
public Person() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id.get();
}
public void setId(Integer id) {
this.id.set(id);
}
public IntegerProperty idProperty() {
return id;
}
#Basic
#Column(name = "name")
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.person", cascade=CascadeType.ALL, orphanRemoval = true)
public Set<PersonTeam> getPersonTeams() {
return personTeams;
}
public void setPersonTeams(Set<PersonTeam> personTeams) {
this.personTeams = personTeams;
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (getId() != null ? !getId().equals(person.getId()) : person.getId() != null) return false;
if (getName() != null ? !getName().equals(person.getName()) : person.getName() != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
return result;
}
/**
* Returns an Observable List that must remain unchanged.
* Unfortunately there is no RO Observable List Interface to refer to.
*/
#Transient
public ObservableList<Team> getTeams() {
return teams.get();
}
#Transient
public ReadOnlyListProperty<Team> teamsProperty() {
return teams;
}
public void addTeam(Team team, String createdBy, Date createdDate) {
final PersonTeam personTeam = new PersonTeam(this, team);
personTeam.setCreatedBy(createdBy);
personTeam.setCreatedDate(createdDate);
if( !personTeams.add(personTeam) ) {
LOG.error("Failed to add personTeam " + personTeam + " to collection personTeams " + personTeams);
}
if( !team.getPersonTeams().add( personTeam ) ) {
LOG.error("Failed to add personTeam " + personTeam + " to collection team.getPersonTeams " + team.getPersonTeams());
}
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
public void removeTeam(Team team) {
PersonTeam personTeam = new PersonTeam( this, team );
team.getPersonTeams().remove( personTeam );
personTeams.removeIf( pt -> pt.getTeam() == team );
personTeam.setPerson( null );
personTeam.setTeam( null );
teams.setAll(personTeams.stream().map(PersonTeam::getTeam).collect(Collectors.toList()));
}
/*
The method is not intended to be used in the GUI.
Use the {#link GUIRepresentable} interface instead.
*/
#Override
public String toString() {
return name.getValue();
}
}
PersonTeam:
#Entity
#Table(name = "person_team")
#AssociationOverrides({
#AssociationOverride(name = "pk.person",
joinColumns = #JoinColumn(name = "PERSON_ID")),
#AssociationOverride(name = "pk.team",
joinColumns = #JoinColumn(name = "TEAM_ID")) })
public class PersonTeam implements java.io.Serializable {
private PersonTeamPk pk = new PersonTeamPk();
private Date createdDate;
private String createdBy;
public PersonTeam() {
}
public PersonTeam(Person person, Team team) {
this.pk.setPerson(person);
this.pk.setTeam(team);
}
#EmbeddedId
public PersonTeamPk getPk() {
return pk;
}
public void setPk(PersonTeamPk pk) {
this.pk = pk;
}
#Transient
public Person getPerson() {
return getPk().getPerson();
}
public void setPerson(Person person) {
getPk().setPerson(person);
}
#Transient
public Team getTeam() {
return getPk().getTeam();
}
public void setTeam(Team team) {
getPk().setTeam(team);
}
#Temporal(TemporalType.DATE)
#Column(name = "CREATED_DATE", nullable = false, length = 10)
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
#Column(name = "CREATED_BY", nullable = false, length = 10)
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PersonTeam that = (PersonTeam) o;
if (getPk() != null ? !getPk().equals(that.getPk())
: that.getPk() != null)
return false;
return true;
}
public int hashCode() {
return (getPk() != null ? getPk().hashCode() : 0);
}
}
PersonTeamPk:
#Embeddable
public class PersonTeamPk implements java.io.Serializable {
private Person person;
private Team team;
#ManyToOne(cascade = CascadeType.ALL)
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
#ManyToOne(cascade = CascadeType.ALL)
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PersonTeamPk that = (PersonTeamPk) o;
if (person != null ? !person.equals(that.person) : that.person != null) return false;
if (team != null ? !team.equals(that.team) : that.team != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (person != null ? person.hashCode() : 0);
result = 31 * result + (team != null ? team.hashCode() : 0);
return result;
}
}
Team:
#Entity
public class Team implements Serializable, Comparable<Team> {
private final IntegerProperty id = new SimpleIntegerProperty(this, "id");
private final StringProperty name = new SimpleStringProperty(this, "name");
private Set<PersonTeam> personTeams = new LinkedHashSet<>();
public Team(String s) {
this.name.set(s);
}
public Team() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id.get();
}
public void setId(Integer id) {
this.id.set(id);
}
public IntegerProperty idProperty() {
return id;
}
#Basic
#Column(name = "name")
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.team", orphanRemoval = true, cascade = CascadeType.ALL)
public Set<PersonTeam> getPersonTeams() {
return personTeams;
}
public void setPersonTeams(Set<PersonTeam> personTeams) {
this.personTeams = personTeams;
}
public static Callback<Team, Observable[]> extractor() {
return (Team p) -> new Observable[]{p.nameProperty()};
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Team team = (Team) o;
if (getId() != null ? !getId().equals(team.getId()) : team.getId() != null) return false;
if (getName() != null ? !getName().equals(team.getName()) : team.getName() != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
return result;
}
#Override
public String toString() {
return name.getValue();
}
#Override
public int compareTo(Team o) {
return Integer.compare(getId(), o.getId());
}
}
I have table
#Entity
#Table(name = "User", schema = "swprojekt", catalog = "")
public class UserEntity {
private String password;
private String email;
private int userId;
private String firstName;
private String lastName;
private String addressHouseNumber;
private String addressStreet;
private String addressCity;
private String addressState;
private String phoneNumber;
private int isAdmin;
#Basic
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Basic
#Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Id
#Column(name = "user_id")
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
#Basic
#Column(name = "first_name")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Basic
#Column(name = "last_name")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Basic
#Column(name = "address_house_number")
public String getAddressHouseNumber() {
return addressHouseNumber;
}
public void setAddressHouseNumber(String addressHouseNumber) {
this.addressHouseNumber = addressHouseNumber;
}
#Basic
#Column(name = "address_street")
public String getAddressStreet() {
return addressStreet;
}
public void setAddressStreet(String addressStreet) {
this.addressStreet = addressStreet;
}
#Basic
#Column(name = "address_city")
public String getAddressCity() {
return addressCity;
}
public void setAddressCity(String addressCity) {
this.addressCity = addressCity;
}
#Basic
#Column(name = "address_state")
public String getAddressState() {
return addressState;
}
public void setAddressState(String addressState) {
this.addressState = addressState;
}
#Basic
#Column(name = "phone_number")
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
#Basic
#Column(name = "is_admin")
public int getIsAdmin() {
return isAdmin;
}
public void setIsAdmin(int isAdmin) {
this.isAdmin = isAdmin;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (userId != that.userId) return false;
if (isAdmin != that.isAdmin) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
if (email != null ? !email.equals(that.email) : that.email != null) return false;
if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;
if (addressHouseNumber != null ? !addressHouseNumber.equals(that.addressHouseNumber) : that.addressHouseNumber != null)
return false;
if (addressStreet != null ? !addressStreet.equals(that.addressStreet) : that.addressStreet != null) return false;
if (addressCity != null ? !addressCity.equals(that.addressCity) : that.addressCity != null) return false;
if (addressState != null ? !addressState.equals(that.addressState) : that.addressState != null) return false;
if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null) return false;
return true;
}
#Override
public int hashCode() {
int result = password != null ? password.hashCode() : 0;
result = 31 * result + (email != null ? email.hashCode() : 0);
result = 31 * result + userId;
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (addressHouseNumber != null ? addressHouseNumber.hashCode() : 0);
result = 31 * result + (addressStreet != null ? addressStreet.hashCode() : 0);
result = 31 * result + (addressCity != null ? addressCity.hashCode() : 0);
result = 31 * result + (addressState != null ? addressState.hashCode() : 0);
result = 31 * result + (phoneNumber != null ? phoneNumber.hashCode() : 0);
result = 31 * result + isAdmin;
return result;
}
}
its called User.
I want to insert the data into it:
#Transactional
public boolean register( UserEntity u){
Query q = em.createNativeQuery("Select * from User where email = ?1", UserEntity.class);
q.setParameter(1, u.getEmail());
List<UserEntity> registeredUser = q.getResultList();
if( registeredUser.isEmpty()) {
try{
u.setPassword(BCrypt.hashpw(u.getPassword(), BCrypt.gensalt(16)));;
em.persist(u);
return true;
}catch( DataAccessException e ){
return false;
}
}
return false;
}
However this keep throwing exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'swprojekt.user' doesn't exist
i have read that it is case sensitive so i tried to rename
#Table(name = "User" ... ) to #Table( name = "user"...)
i have defined
spring.datasource.username = name
spring.datasource.password = password
in application.properties file.
Which did not help. Also when i try to access another table in database it works.
WHat may cause this exception?
Thanks for help.
#EntityScan only identifies which classes should be used by a specific persistence context.
Example:
#EntityScan(basePackages = {"com.project.model"}) // scan JPA entities
And
spring.jpa.hibernate.ddl-auto = create
Update :
If there are other tables, change the table name.
#Table(name = "User_Tbl")
do you have your properties over there??? because most probably the name of the database is not setting for example :
dbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sys //name of the database
jdbc.username=root
jdbc.password=asdadsadsadsa
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.format_sql=false
example for mysql
I'm trying to execute an IN query with by using Spring Data. My model looks like this:
#Entity
#Table(name = "customer", schema = "public", catalog = "postgres")
public class CustomerEntity {
private int id;
private String name;
private int balance;
private String bankId;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "balance")
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
#Basic
#Column(name = "bank_id")
public String getBankId() {
return bankId;
}
public void setBankId(String bankId) {
this.bankId = bankId;
}
And my repository interface looks like this:
#Repository
public interface TransactionsRepository extends JpaRepository<TransactionsEntity, Long> {
List<TransactionsEntity> findByCustomerIdIn(List<CustomerEntity> customerEntities);
}
The problem is that when I try to execute this code
List<TransactionsEntity> transactionsEntitiesList = transactionsRepository.findByCustomerIdIn(customerEntitiesList);
I get this exception:
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value element [org.example.domain.admin.CustomerEntity#6a1a2a4] did not match expected type [java.lang.String (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value element [org.example.domain.admin.CustomerEntity#6a1a2a4] did not match expected type [java.lang.String (n/a)]
Update: TransactionsEntity.class:
#Entity
#Table(name = "transactions", schema = "public", catalog = "postgres")
public class TransactionsEntity {
private String id;
private String amount;
private String customerId;
#Id
#Column(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Basic
#Column(name = "amount")
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
#Basic
#Column(name = "customer_id")
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TransactionsEntity that = (TransactionsEntity) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
if (amount != null ? !amount.equals(that.amount) : that.amount != null) return false;
if (customerId != null ? !customerId.equals(that.customerId) : that.customerId != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (amount != null ? amount.hashCode() : 0);
result = 31 * result + (customerId != null ? customerId.hashCode() : 0);
return result;
}
}
As it says in the exception Spring expects a String because your customer_id in your TransactionEntity is a String, but you are inputting a CustomerEntity. Instead you should input a List<String> with the list of your customer ids.
Btw shouldn't your customer_id be an int assuming you set it to the id of your CustomerEntity?
Then you could do something like
List<Integer> customerIds = customerEntitiesList.stream().map(CustomerEntity::getId).collect(Collectors.toList());
There are the entities Cookbook, Recipe. It's a ManyToMany relation: a cookbook can have multiple recipes and a recipe can be assigned to multiple cookbooks. So I added the entity CookbookRecipe and connected the entities as OneToMany.
Where to put a method to add/remove the relation between Cookbook and Recipe - does this method has to add a new CookbookRecipe and add this CookbookRecipe to Cookbook and Recipe?
In my understanding I would expect a
public void addRecipe(Recipe recipe) {
CookbookRecipe relation = new CookbookRecipe();
relation.setCookbook(this);
relation.setRecipe(recipe);
this.cookbookRecipes.add( relation );
}
Is this the right direction?
Would I add this method to the Cookbook DAO or Recipe DAO or put this into a service?
#Entity
public class Cookbook {
private Integer id;
private String title;
private Collection<CookbookRecipe> cookbookRecipes;
private Collection<CookbookSortlevel> cookbookSortlevels;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Basic
#Column(name = "title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cookbook cookbook = (Cookbook) o;
if (id != null ? !id.equals(cookbook.id) : cookbook.id != null) return false;
if (title != null ? !title.equals(cookbook.title) : cookbook.title != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
return result;
}
#OneToMany(mappedBy = "cookbook", fetch = FetchType.EAGER)
public Collection<CookbookRecipe> getCookbookRecipes() {
return cookbookRecipes;
}
public void setCookbookRecipes(Collection<CookbookRecipe> cookbookRecipes) {
this.cookbookRecipes = cookbookRecipes;
}
#OneToMany(mappedBy = "cookbook")
public Collection<CookbookSortlevel> getCookbookSortlevels() {
return cookbookSortlevels;
}
public void setCookbookSortlevels(Collection<CookbookSortlevel> cookbookSortlevels) {
this.cookbookSortlevels = cookbookSortlevels;
}
}
#Entity
#Table(name = "cookbook_recipe", schema = "", catalog = "")
public class CookbookRecipe {
private Integer id;
private Recipe recipe;
private Cookbook cookbook;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CookbookRecipe that = (CookbookRecipe) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
return result;
}
#ManyToOne
#JoinColumn(name = "recipe_id", referencedColumnName = "id")
public Recipe getRecipe() {
return recipe;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
}
#ManyToOne
#JoinColumn(name = "cookbook_id", referencedColumnName = "id", nullable=false,insertable=false,updatable=false )
public Cookbook getCookbook() {
return cookbook;
}
public void setCookbook(Cookbook cookbook) {
this.cookbook = cookbook;
}
}
#Entity
public class Recipe {
private Integer id;
private String title;
private String text;
private Collection<RecipeIngredient> recipeIngredients;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Basic
#Column(name = "title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Basic
#Column(name = "text")
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Recipe recipe = (Recipe) o;
if (id != null ? !id.equals(recipe.id) : recipe.id != null) return false;
if (title != null ? !title.equals(recipe.title) : recipe.title != null) return false;
if (text != null ? !text.equals(recipe.text) : recipe.text != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (text != null ? text.hashCode() : 0);
return result;
}
#OneToMany(mappedBy = "recipe")
public Collection<RecipeIngredient> getRecipeIngredients() {
return recipeIngredients;
}
public void setRecipeIngredients(Collection<RecipeIngredient> recipeIngredients) {
this.recipeIngredients = recipeIngredients;
}
}
Are there any github projects handling this you could suggest?
This is, for me, the right direction. The code looks good
I think you should add it in the CookBookDAO because the Cookbook contains Recipes not the opposite
I have three entities: Account, AccountAttribut and Attribut. Account and Attribut are associated via AccountAttribut in a many-to-many relationship like it is described here (1). AccountAttribut is a join table entity that holds an additional attribute.
I try to build a HQL string that delivers all Accounts with the "wert"-property "John" in AccountAttribut and the name-property "FirstName" in Attribut.
I dont find the right HQL string. Can you help me out?
(1): http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/ "Mapping a many-to-many join table with extra column using JPA"
I tried this query:
List<Account> queried_accounts = HibernateUtils.queryList(
session.createQuery(""
+ "from Account as acc"
+ " full join acc.accountAttributes as accAtt"
+ " inner join accAtt.aa_pk.attribut as attr"
+ " where attr.name='FirstName' and accAtt.wert='John'")
);
and i get this error message:
ERROR: You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'full outer join account_attribut accountatt1_ on
account0_.account_id=accountatt' at line 1
UPDATE:
I changed the query to:
List<Account> queried_accounts = HibernateUtils.queryList(
session.createQuery(""
+ "from Account as acc"
+ " inner join acc.accountAttributes as accAtt"
+ " inner join accAtt.aa_pk.attribut as attr"
+ " where attr.name='FirstName' and accAtt.wert='John'")
);
This seems to work.
But now i got a new Problem: queried_accounts does not seem to be a List of Accounts. If i get an object out of queried_accounts and try to apply account methods on it, i get an Exception at runtime.
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to
com.computacenter.qct.pojos.Account
These are relevant code extracts:
Account:
#Entity
#Table(name = "account")
public class Account {
private Long accountId;
private List<AccountAttribut> accountAttributes = new LinkedList<AccountAttribut>();
private Person person;
private Zielsystem zielsystem;
public Account() {
}
#Id
#GeneratedValue
#Column(name = "account_id", nullable = false)
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "aa_pk.account", cascade = {
CascadeType.PERSIST, CascadeType.MERGE })
#Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
public List<AccountAttribut> getAccountAttributes() {
return accountAttributes;
}
public void setAccountAttributes(List<AccountAttribut> accountAttribute) {
this.accountAttributes = accountAttribute;
}
#ManyToOne
#JoinColumn(name = "person_id")
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
#ManyToOne
#JoinColumn(name="zielsystem_id")
public Zielsystem getZielsystem() {
return zielsystem;
}
public void setZielsystem(Zielsystem zielsystem) {
this.zielsystem = zielsystem;
}
}
AccountAttribut:
#Entity
#Table(name="account_attribut")
#AssociationOverrides({
#AssociationOverride(name="aa_pk.account", joinColumns = #JoinColumn(name="account_id")),
#AssociationOverride(name="aa_pk.attribut", joinColumns = #JoinColumn(name="attribut_id"))
})
public class AccountAttribut {}
private AccountAttributPk aa_pk = new AccountAttributPk();
#Column(name="wert")
private String wert;
#EmbeddedId
public AccountAttributPk getAa_pk() {
return aa_pk;
}
public void setAa_pk(AccountAttributPk aa_pk) {
this.aa_pk = aa_pk;
}
#Transient
public Account getAccount() {
return getAa_pk().getAccount();
}
public void setAccount(Account account) {
getAa_pk().setAccount(account);
}
#Transient
public Attribut getAttribut() {
return getAa_pk().getAttribut();
}
public void setAttribut(Attribut attribut) {
getAa_pk().setAttribut(attribut);
}
public String getWert() {
return wert;
}
public void setWert(String wert) {
this.wert = wert;
}
public boolean equals(Object o) {
if (this== o) return true;
if (o ==null|| getClass() != o.getClass()) return false;
AccountAttribut that = (AccountAttribut) o;
if (getAa_pk() !=null?!getAa_pk().equals(that.getAa_pk()) : that.getAa_pk() !=null) return false;
return true;
}
public int hashCode() {
return (getAa_pk() !=null? getAa_pk().hashCode() : 0);
}
}
AccountAttributPk:
public class AccountAttributPk implements Serializable {
private static final long serialVersionUID = -1551814445010872872L;
private Account account;
private Attribut attribut;
#ManyToOne
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
#ManyToOne
public Attribut getAttribut() {
return attribut;
}
public void setAttribut(Attribut attribut) {
this.attribut = attribut;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
AccountAttributPk that = (AccountAttributPk) o;
if (account != null ? !account.equals(that.account) : that.account != null)
return false;
if (attribut != null ? !attribut.equals(that.attribut)
: that.attribut != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (account != null ? account.hashCode() : 0);
result = 31 * result + (attribut != null ? attribut.hashCode() : 0);
return result;
}
}
Attribut
#Entity
#Table(name="Attribut")
public class Attribut {
private Long attributId;
private String name;
private List<PersonAttribut> personenAttribute = new LinkedList<PersonAttribut>();
private List<AccountAttribut> accountAttribute = new LinkedList<AccountAttribut>();
private List<BerechtigungsobjektAttribut> berechtigungsobjektAttribute = new LinkedList<BerechtigungsobjektAttribut>();
public Attribut() {}
public Attribut(String name) {
this.name = name;
}
#Id
#GenericGenerator(name="generator", strategy="increment")
#GeneratedValue(generator="generator")
#Column(name="attribut_id", nullable=false)
public Long getAttributId() {
return attributId;
}
public void setAttributId(Long attributId) {
this.attributId = attributId;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pa_pk.attribut", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public List<PersonAttribut> getPersonenAttribute() {
return personenAttribute;
}
public void setPersonenAttribute(List<PersonAttribut> personenAttribute) {
this.personenAttribute = personenAttribute;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "aa_pk.attribut", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public List<AccountAttribut> getAccountAttribute() {
return accountAttribute;
}
public void setAccountAttribute(List<AccountAttribut> accountAttribute) {
this.accountAttribute = accountAttribute;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "ba_pk.attribut", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public List<BerechtigungsobjektAttribut> getBerechtigungsobjektAttribute() {
return berechtigungsobjektAttribute;
}
public void setBerechtigungsobjektAttribute(
List<BerechtigungsobjektAttribut> berechtigungsobjektAttribute) {
this.berechtigungsobjektAttribute = berechtigungsobjektAttribute;
}
#Override
public String toString() {
return name;
}
#Override
public boolean equals(Object other) {
if (other == null)
return false;
if (this == other)
return true;
if (this.getClass() != other.getClass())
return false;
final Attribut otherAccount = (Attribut) other;
return EqualsUtils.nullSafeEquals(this.getName(), otherAccount.getName());
}
#Override
public int hashCode() {
final int PRIME = 42;
return this.name.hashCode() * PRIME;
}
}