Trying to get value from 2 joined tables with getter, have 2 models Customer and Address.
#Setter
#Getter
#Data
#Entity
#Accessors(chain = true)
#Table(name = "customer")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "phoneNumber")
private String phoneNumber;
#Column(name = "address")
private String address;
}
#Setter
#Getter
#Data
#Entity
#Accessors(chain = true)
#Table(name = "address")
public class Address implements Serializable {
#Id
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "address")
private String address;
#Column(name = "zipcode")
private String zipcode;
#Column(name = "number")
private Integer number;
#ManyToOne
#JoinColumn(name="customer")//
private Customer customerBean;
}
Address Repository with this query :
#Query( value = "SELECT ad FROM Address ad, Customer c WHERE ad.customer = c.id and c.id = 1)
Optional <List<Address>> getAddress();
Try to get with getter :
Optional<List<Address>> address = getAddress();
System.out.println(address.getAddress()); //success
System.out.println(address.getAddress().get().get(0).getCustomerBean().getName()) //null value
Successfully get data address from table Address, but if get Customer name get null value, any suggestion?
Try the following in your #Query definition:
#Query(value = "SELECT ad FROM Address ad JOIN FETCH ad.customer WHERE ad.customer = 1")
Optional <List<Address>> getAddress();
Related
I tried several solutions to my SQL query but it seems like I miss something.
I want to get a List<Product> from a nativeQuery.
And I have a relationship between my User entity and Product entity as One to Many.
Here is my both entites -> Product
#Entity
#Data
#Table(name = "product")
#NoArgsConstructor
#AllArgsConstructor
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#CreationTimestamp
#Column(updatable = false)
private Timestamp createdDate;
#UpdateTimestamp
private Timestamp lastModifiedDate;
private String imageURL;
private Long productCode;
#Size(min = 3,max = 100)
private String productName;
#Size(min = 5,max = 100)
private String details;
private BigDecimal price;
private ProductCategory productCategory;
}
User ->
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true,nullable = false)
private String phoneNumber;
#Size(min = 5, max = 25, message = "Username length should be between 5 and 25 characters")
#Column(unique = true, nullable = false)
private String userName;
#CreationTimestamp
#Column(updatable = false)
private Timestamp createdDate;
#UpdateTimestamp
private Timestamp lastModifiedDate;
#Column(unique = true, nullable = false)
#NotNull
private String email;
#Size(min = 5, message = "Minimum password length: 5 characters")
#NotNull
private String password;
#OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
private List<Product> products;
#Transient
#OneToMany(fetch = FetchType.LAZY,mappedBy = "product",cascade = CascadeType.ALL,orphanRemoval = true)
private List<ProductInquiry> productInquiries;
private Role role;
}
Here in this query I need to return all products associated with the given user_id.
#Query(value = "SELECT new egecoskun121.com.crm.model.entity.Product(p.ID,p.CREATED_DATE,p.LAST_MODIFIED_DATE,p.IMAGEURL,p.PRODUCT_CODE,p.PRODUCT_NAME,p.DETAILS,p.PRICE,p.PRODUCT_CATEGORY) FROM PRODUCT AS p WHERE {SELECT PRODUCT_ID FROM USERS_PRODUCTS WHERE USER_ID=:id }",nativeQuery = true)
List<Product> findAllProductsById(#Param("id")Long id);
The problem is that you are using a HQL query but you've set native=true. Setting native=true means that you want to run a SQL query.
This HQL query should work:
#Query("select p from User u join u.products p WHERE u.id = :id")
List<Product> findAllProductsById(#Param("id")Long id);
I have strange problem. I have entity Company, Branch and Address.
Company has list of branch and every branch has address.
Im trying to persist branch with not exist before address entity, but Address is persist with nulls columns.
#Data
#Entity
#Indexed
#Table(name = "company")
public class Company {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
private String id;
#Field
#Column(name = "full_name", nullable = false, unique = true)
private String fullName;
#OneToMany(mappedBy = "company")
private Set<Branch> branches;
}
#Data
#Entity
#Table(name = "branch")
public class Branch {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column
private String phone;
#Column
private String email;
#OneToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;
#ManyToOne
#JoinColumn(name = "company_id", referencedColumnName = "id")
private Company company;
}
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column
private String street;
#OneToOne(mappedBy = "address")
private Company company;
#OneToOne(mappedBy = "address")
private Branch branch;
}
Service ...
public Integer addBranch(BranchDto branchDto) {
Branch branch = modelMapper.map(branchDto, Branch.class);
Company company = companyRepository.getCompanyById(branchDto.getCompanyId());
branch.setCompany(company);
return branchRepository.save(branch).getId();
}
Dto...
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class BranchDto {
private Integer id;
private String phone;
private String email;
private AddressDto address;
private String companyId;
}
And that is effect...
Debugger...
What is the problem? Can you help me ?
You are using 'mappedBy' with the same id, It only works with the first one he find.
Try to change to other id.
I'm just learning Spring Data. I want to map a database view Entity with a simple Entity and pass to DTO which will contain columns both entities. I understand that I can use a special database view but I need to map precisely entities of Spring Data.
I have a database view Entity "MentorStudents":
#Entity
#Table(name = "mentor_students")
#Immutable
public class MentorStudents implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "mentor_id", updatable = false, nullable = false)
private Long mentorId;
//This entity I need to map
private Mentor mentor;
#Column(name = "active_students")
private Integer activeStudents;
public MentorStudents() {
}
//getters, setters, equals, hashCode
}
A database view sql of an above entity is:
SELECT id AS mentor_id, active_students
FROM mentor
LEFT JOIN ( SELECT mentor_id, count(mentor_id) AS active_students
FROM contract
WHERE close_type IS NULL
GROUP BY mentor_id) active ON mentor.id = active.mentor_id
ORDER BY mentor.id;
And I have a simple Entity "Mentor":
#Entity
#Table(name = "mentor")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Mentor implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#NotNull
#Column(name = "first_name", nullable = false)
private String firstName;
#NotNull
#Column(name = "last_name", nullable = false)
private String lastName;
#Column(name = "patronymic")
private String patronymic;
#Column(name = "phone")
private String phone;
#NotNull
#Column(name = "email", nullable = false)
private String email;
#Column(name = "skype")
private String skype;
#Column(name = "country")
private String country;
#Column(name = "city")
private String city;
#Column(name = "max_students")
private Long maxStudents;
//getters, setters, equals, hashCode
I have to get a DTO which contains all Mentor fields and an "activeStudents" MentorStudents field without a "mentorId" field. How do it?
Use spring data projection:
public interface YourDto {
// all Mentor get fields
String getFirstName();
...
// activeStudents get field
Integer getActiveStudents();
}
public interface YourRepository extends JpaRepository<YourEntity, Integer> {
#Query(value = "select ...(all fields match YourDto) from Mentor m, MentorStudents s where m.id = s.mentorId and m.id = ?1")
Optional<YourDto> findMyDto(Integer mentorId);
}
I have a SQL query like this:
"Select UIProfileID from UserTable where UPPER(UserID) = UPPER('?1')".
I want to convert it to Spring JPA.
I want to write getUIProfileId() and return Integer. But I don't know how to implement. Because User table doesn't have UIProfileId column that it was joined from UIProfileTable table. Please help me solve it.
Currently, I have tables:
User.java
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Table(name = "UserTable")
public class User {
#Column(name = "UserID", length = 32, nullable = false)
#Id
private String name;
#ManyToOne
#JoinColumn(name = "DomainID", nullable = false)
private Domain domain;
#Column(name = "Password", length = 32, nullable = false)
private String password;
#ManyToOne
#JoinColumn(name = "UIProfileID", nullable = false)
private UIProfile uiProfile;
#Column(name = "ResPerpage", nullable = false)
private Integer resperpage;
#Column(name = "DefaultTab")
private Integer defaulttab;
#ManyToOne
#JoinColumn(name = "AdminProfile")
private AdminProfiles adminProfile;
#Column(name = "LanguageId")
private Integer languageId;
}
UIProfile.java
#Entity
#Getter
#Setter
#Table(name = "UIProfileTable")
public class UIProfile implements Serializable {
#Id
#Column(name = "UIProfileID", length = 11, nullable = false)
private Integer id;
#Column(name = "UIProfileName", length = 32, nullable = false)
private String name;
#OneToMany(mappedBy = "id.uiProfile")
private List<UIProfileTopLevel> topLevels;
}
UserRepository.java
public interface UserRepository extends Repository<User, String> {
Optional<User> findOne(String name);
#Query("Select UIProfileID from User where UPPER(UserID) = UPPER('admin')")
Integer getUIProfileId();
}
You can try this:
#Query("SELECT u.uiProfile.id from User u where UPPER(u.name)=UPPER('admin')")
Integer getUIProfileId();
Here User is the domain class name and u is the reference of User. with u we will access User's field NOT the column name which are specified with #Column or #JoinColumn Ex : #JoinColumn(name = "UIProfileID", nullable = false).
I'm trying to achieve something like sql command below by using HQL and JPA.
Instead of "SELECT user_id..." I need SELECT OBJECT(o).
SELECT user_id FROM posix_user o INNER JOIN postgre_user n ON n.id=o.user_id WHERE n.name='USERNAME2'
I have some problems with this part of the code in JPA DAO:
public List<PosixUserEntity> listPosixUsers(final String uid_number) {
final StringBuilder queryString = new StringBuilder("SELECT OBJECT(o) FROM ");
queryString.append(this.entityClass.getSimpleName());
queryString.append(" o JOIN com.services.dao.user.jpa.UserEntity n ON (n.id=o.user_id) WHERE n.name LIKE :uid_number");
final Query findByNameQuery = entityManager.createQuery(queryString.toString()).setParameter("uid_number", uid_number);
return findByNameQuery.getResultList();
}
JOIN ON is not allowet here and I did not know how to replace it.
Also how can I replace com.services.dao.user.jpa.UserEntity by something cleaner.
There is my Entites, they may need to be improved:
#Entity
#Table(name = "posix_user")
public class PosixUserEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
//#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private String user_id;
#Column(name = "uid_number")
private String uid_number;
#Column(name = "home_directory")
private String home_directory;
#Column(name = "login_shell")
private String login_shell;
#Column(name = "group_id")
private String group_id;
//getters,setters....
#Entity
#Table(name = "postgre_user")
#SQLDelete(sql = "update postgre_user set status = 'removed' where id = ?")
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name", unique = true, nullable = false)
private String name;
#Column(name = "password")
private String password;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private UserStatus status;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "usertype")
private String userType;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserRoleTargetGroupEntity> userRoleTargetGroupEntity;
#Column(name = "last_login")
private String lastLogin;
#Column(name = "previous_login")
private String previousLogin;
#JsonIgnore
#Column(name = "change_password_flag")
private Boolean userPasswordResetFlag;
#OneToOne(cascade=CascadeType.ALL)
#PrimaryKeyJoinColumn
private PosixUserEntity posixUserEntity;
You may also need to know that FOREIGN KEY (user_id) REFERENCES postgre_user (id) - it should look like that
Can you know how can I modify my SELECT?
I've tested a simplified version of your classes
#Entity
#Table(name = "posix_user")
public class PosixUserEntity {
#Id
#Column(name = "user_id")
private Long user_id;
// getter + setter
}
#Entity
#Table(name = "postgre_user")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#OneToOne(cascade=CascadeType.ALL)
#PrimaryKeyJoinColumn
private PosixUser posixUserEntity;
// getter + setter
}
And this JPQL query works as expected
String jpql = "SELECT p "
+ "FROM UserEntity n JOIN n.posixUserEntity p "
+ "WHERE n.name LIKE :uid_number)";
JOIN is allowed because you have mapped the relationship in UserEntity.
and you don't need to specify the complete name of your entity class.
Check if it has been included when you define your persistence unit.
Hope this helps.