How to create custom query in spring for getting all user who follow me from database..this is my repository
#Repository
public interface FollowRepository extends JpaRepository<Follow, Long> {
#Query("Select f from Follow f where f.user = :user and f.status = 'follow'")
List<Follow> findByUser (#Param("user") User user);
}
and this is my table in database
CREATE TABLE IF NOT EXISTS `follow`(
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`user_id` BIGINT,
`follower_id` BIGINT,
`status` ENUM ('follow','blocked') NOT NULL,
FOREIGN KEY (user_id) REFERENCES `user`(id),
FOREIGN KEY (follower_id) REFERENCES `user`(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#Query("Select f from Follow f where f.userId = ?1 and f.status = ?2")
List<Follow> findByUser (Integer userId, String status);
You could also:
List<Follow> findByUserAndStatus(User user, String status);
EDIT: Having your status as an ENUM in your table can make it stressful when making new enums. I'd prefer having the status column as a VARCHAR and in your entity your getter for that field can be:
#Basic
#Column(name = "status")
#Enumerated(EnumType.STRING)
public StatusEnum getStatus(){ return this.getStatus; }
Related
I'm new to JPA and trying to understand if there's a way to make an Entity where one column is coming from another table that is linked by a foreign key. For example, consider the following tables:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `jobs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11),
PRIMARY KEY (`id`),
CONSTRAINT `fk_jobs_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
);
Now I want to make an Entity for the "jobs" table that will include the user.email. I know I can do something like
#Entity
#Table(name = "jobs")
public class JobEntity {
#Id
#Column(name = "id")
private Long id;
#Column(name = "user_id")
private Long userId;
#Formula("(select user.email FROM user WHERE user.id = user_id)")
private String userEmail;
But I feel there's a way I can better leverage the foreign key relationship, but I'm not sure how. I was looking into #JoinColumn but was not seeing the result I wanted since the foreign key is a different column in my Entity. Is there a better way rather than using #Forula to do this?
I don't really understand this. I'm sure #JoinColumn can accomplish the behavior you're looking for.
I was looking into #JoinColumn but was not seeing the result I wanted since the foreign key is a different column in my Entity
Example:
#Entity
#Table(name = "jobs")
public class KronosFileEntity {
#Id
#Column(name = "id")
private Long id;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumn = "id")
private User user;
}
Then you can access the email like job.getUser().getEmail()
Or add a convenience method if that helps
public String getUserEmail() {
return user.getEmail();
}
Then
job.getUserEmail()
I am working with Spring MVC + Hibernate ( Spring data jpa ).
Here I am not getting how to create a table in Hibernate for the following scenario.
I have two tables :
1) User Details
2) Branch
Now, For every user, there is a field for branch, and that value should be from Branch table.
I have knowledge of OneToOne in hibernate. But it inserts a new entry for users branch field in Branch table. What I want is that, when I save user details in User Table, branch details should be just a reference from Branch table for matching row.
Thank you in advance
Suppose your branches can be identified by their names:
UserDetails user = new UserDetails();
...
user.setBranch(branchRepository.findOneByName());
...
userDetailsRepository.save(user);
Having:
#Entity
public class UserDetails {
#Id
#GeneratedValue
Long id;
#ManyToOne
Branch branch;
...
}
#Entity
public class Branch {
#Id
#GeneratedValue
Long id;
...
}
public interface BranchRepository extends Repository<Branch, Long> {
...
}
public interface UserDetailsRepository extends Repository<UserDetails, Long> {
...
}
You can use the User-Branch relationship by controlling the association through its Foreign Key.
And inside the User class, you will specify the OneToOne mapping as follows:
#OneToOne
#JoinColumn(name="User_Branch_ID")
private Branch branch;
And this "User_Branch_ID" refers to the foreign key which you have created while creating the User database table as follows:
create table BRANCH (
branch_id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
city VARCHAR(30) NOT NULL,
country VARCHAR(30) NOT NULL,
PRIMARY KEY (address_id)
);
create table USER (
user_id BIGINT NOT NULL AUTO_INCREMENT,
user_branch_id BIGINT NOT NULL,
first_name VARCHAR(30) NOT NULL,
last_name VARCHAR(30) NOT NULL,
PRIMARY KEY (user_id),
CONSTRAINT user_branch FOREIGN KEY (user_branch_id) REFERENCES BRANCH ( branch_id)
);
step 1: create a view
create view v_BRANCH_USER as
select
a.branch_id, a.name , a.city, a.country
b.user_id,b.first_name, b.last_name
from BRANCH a, USER b
where a.branch_id = b.user_branch_id
step 2: create a pojo and mapping to hibernate as a table
#Entity
#Table(name = "v_BRANCH_USER")
public class VBranchUser
String userId;
....
}
step 3: You can query it as a table (Criteria, HQL ..)
I don't see an example anywhere so I am not sure this is possible. But basically, I am trying to see if I can bind a field in an entity to
Map<Skill,Set<Rating>> ratings;
CREATE TABLE Worker (
ID BIGINT PRIMARY KEY,
);
CREATE TABLE Skill (
ID BIGINT PRIMARY KEY,
name VARCHAR(32) NOT NULL,
UNIQUE (name)
);
CREATE TABLE WorkerSkillRating (
ID BIGINT PRIMARY KEY,
WorkerID BIGINT NOT NULL,
SkillID BIGINT NOT NULL,
Rating INT,
FOREIGN KEY (WorkerID) REFERENCES Worker (ID),
FOREIGN KEY (SkillID) REFERENCES Skill (ID),
FOREIGN KEY (Rating) REFERENCES Rating (ID)
);
CREATE TABLE Rating (
ID BIGINT PRIMARY KEY,
score TINYINT NOT NULL,
comments VARCHAR(256)
);
Entities
#Entity
public class Skill {
#Id
private Long id;
private String name;
public Skill(String name) {
this();
this.name = name;
}
public Skill() {
this.id = Math.abs( new Random().nextLong());
}
}
#Entity
public class Worker {
#Id
private Long id;
// The open question
public Map<Skill, Set<Rating>> ratings;
}
#Entity
public class Rating {
#Id
private Long id;
private Byte score;
private String comments;
}
According to the JSR-0038 the JPA spec. When using Map, the following combination are just allowed: Basic Type, Entities and Embeddables.
Map<Basic,Basic>
Map<Basic, Embeddable>
Map<Basic, Entity>
Map<Embeddable, Basic>
Map<Embeddable,Embeddable>
Map<Embeddable,Entity>
Map<Entity, Basic>
Map<Entity,Embeddable>
Map<Entity, Entity>
I don’t think there is pretty much deal to have a possible mapping in the way that you want but that is out of the specs and most of the providers follow them, I think that mapping is not very common at all.
"worker has many skills and he may have been given many ratings on a
single skill. "
Then add to the skill class a Set<Ratings>, instead of nested directly in the map as the value of it.
It might not answer your question with the map but...
It looks like your rating table is unnecessary.
You could instead have
CREATE TABLE Worker (
ID BIGINT PRIMARY KEY,
);
CREATE TABLE Skill (
ID BIGINT PRIMARY KEY,
name VARCHAR(32) NOT NULL,
UNIQUE (name)
);
CREATE TABLE WorkerSkill (
ID BIGINT PRIMARY KEY,
WorkerID BIGINT NOT NULL,
SkillID BIGINT NOT NULL,
score TINYINT NOT NULL,
comments VARCHAR(256)
FOREIGN KEY (WorkerID) REFERENCES Worker (ID),
FOREIGN KEY (SkillID) REFERENCES Skill (ID)
);
Note I moved the rating information to WorkerSkill table.
Then you can map your entities per below
#Entity
public class Skill {
#Id
private Long id;
private String name;
// Getter setters const etc
}
#Entity
public class WorkerSkill {
#Id
private Long id;
private int score;
private String comments;
#ManyToOne
private Skill skill;
#ManyToOne
private Worker worker;
// Getter setters const etc
}
#Entity
public class Worker {
#Id
private Long id;
#OneToMany
public List<WorkerSkill> workerSkills = new ArrayList<>();
// Getter setters const etc
}
Then you can access all worker's skill using worker.getWorkerSkill();
In a spring mvc app using hibernate over MySQL, I am encountering problems when I try to create polymorphic subclasses that inherit their id from a BaseEntity. You can see my intended use when you read my AccessLog class below, which has properties of type BaseEntity. The actor_entity and target_entity properties should each be fillable with a variety of different types of entities, such as User, OutsideSystem, Document, etc., each of which inherit from BaseEntity.
How do I set this up in code?
Here is my current java:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
protected Integer id;
//other stuff
}
#Entity
#Table(name="users")
public class User extends BaseEntity{
//other stuff
}
#Entity
#Table(name = "accesslogs")
public class AccessLog extends BaseEntity{
#ManyToOne
#JoinColumn(name = "actorentity_id")
private BaseEntity actor_entity;
#ManyToOne
#JoinColumn(name = "targetentity_id")
private BaseEntity target_entity;
#Column(name="action_code")
private String action;
}
Here is my current DDL:
CREATE TABLE IF NOT EXISTS baseentity(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS accesslogs(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
actorentity_id int(11) UNSIGNED NOT NULL,
targetentity_id int(11) UNSIGNED NOT NULL,
action_code varchar(100),
access_date DATETIME
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE roles (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
role varchar(20) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE users (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
login varchar(20) NOT NULL,
password varchar(20) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE user_roles (
user_id int(11) UNSIGNED NOT NULL,
role_id int(11) UNSIGNED NOT NULL,
KEY user (user_id),
KEY role (role_id)
) ENGINE=InnoDB;
Why do you need BaseEntity annotate with Entity? You don't need to specify #Inheritance(strategy = InheritanceType.JOINED). BaseEntity should have #MappedSuperclass annotation
And you don't need to create baseentity table
I would like to implement inheritance in Hibernate.
I created ObjectClass object:
#Entity
#Table(name = "object")
#Inheritance(strategy = InheritanceType.JOINED)
public class ObjectClass {
private id;
}
and CodeTable object that inhertance Object class:
#Entity
#ForeignKey(name = "id")
#Table(name = "code_table")
public class CodeTable extends ObjectClass{
private String description;
}
in the database
object table is:
CREATE TABLE `object` (
`id` bigint(11) NOT NULL auto_increment,
PRIMARY KEY (`id`),
)
code_table table is:
-
CREATE TABLE `code_table` (
`id` bigint(11) NOT NULL auto_increment,
`description` varchar(45) character set latin1 default NULL,
PRIMARY KEY (`id`),
KEY `FK_object` (`id`),
CONSTRAINT `FK_object` FOREIGN KEY (`id`) REFERENCES `object` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
)
I wrote the following code to retreive data from codeTable:
#SuppressWarnings( "unchecked" )
#Transactional( readOnly = true, propagation = Propagation.REQUIRED )
public Collection<CodeTable> findAll() {
Session session = getSessionFactory().getCurrentSession();
return
session.createCriteria( persistentClass
).setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY
).list();
}
I gets empty list although there is one record in codetable table.
When I write the following SQL in my database:
SELECT * FROM `code_table`
I get:
id= 1,
description = company.
What went wrong in my Hibernate definition? How can I retrieve the object?
EDITED:
My hibernate.cfg.xml file looks like this:
<hibernate-configuration>
<session-factory>
<mapping class="com.mycompany.model.CodeTable" />
<mapping class="com.mycompany.model.ObjectClass" />
</session-factory>
</hibernate-configuration>
Your mappings and table structure are (roughly) correct for a JOINED inheritance strategy and I cannot reproduce your problem.
I use the following mappings (which are basically the one you provided):
#Entity
#Table(name = "object")
#Inheritance(strategy = InheritanceType.JOINED)
public class ObjectClass {
#Id #GeneratedValue
private Long id;
public ObjectClass() { }
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
}
And
#Entity
#ForeignKey(name = "id")
#Table(name = "code_table")
public class CodeTable extends ObjectClass{
private String description;
public CodeTable() { }
public String getDescription() { return description; }
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "CodeTable [getDescription()=" + getDescription() + ", getId()="
+ getId() + "]";
}
}
The following tables:
create table code_table (
description varchar(255),
id bigint not null,
primary key (id)
)
create table object (
id bigint not null,
primary key (id)
)
alter table code_table
add constraint id
foreign key (id)
references object
And the following parent/child records:
insert into object values (1);
insert into code_table(id, description) values (1, 'foo');
And running your criteria query:
session.createCriteria(CodeTable.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list();
Returns:
CodeTable [getDescription()=foo, getId()=1]
Everything works as expected.
References
JPA 1.0 Specification
2.1.10 Inheritance Mapping Strategies
Hibernate Annotations Reference Guide
2.2.4. Mapping inheritance
How does your mapping looks like ?
Have you read this section in the Hibernate doc ?
Inheritance mapping in Hibernate
As you can read in the link I provided above, your mapping is not correct. You have to let Hibernate know that the code_table class inherits from the object class, and you 'll have to let Hibernate know how this link exists in the database.