Hi i am writing an spring mvc, employee application using mysql database,hibernate annotations and jsp . The database contains one table "Empdata" where empid is primary key.And there is a column "team" in "Empdata".I want to select employees in a specific team, example all the details of employees in "Team1".Here i can perform delete and edit operations in the application. For delete opertaion i am using
sessionfactory.getCurrentSession().createQuery("DELETE FROM Resource WHERE empid=" +resource.getEmpId()).executeUpdate();
query.I know the commandline query for select is
SELECT * FROM EmpData ERE EMPLTEAM ="Team1"
I want to know how to convert this query into hibernate.
please help,thanks in advance..
you can convert the query in the following way:
String sql = "select ed from EmpData ed where emplTeam = :emplTeam";
Query query = session.createQuery(sql);
query.setParameter("emplTeam ", team);
List<EmpData> empDataList = (List<EmpData>)query.list();
but you should have a class called EmpData containing a property emplTeam similar to the following:
#Entity
#Table(name = "EmpData")
class EmpData {
....
#Column(name = "EMPLTEAM")
private String emplTeam;
public String getEmplTeam() {
return emplTeam;
}
public void setEmplTeam(String emplTeam) {
this.emplTeam = emplTeam;
}
}
(I used annotations hibernate .. but you can do it the same way using .hbm.xml files)
For example
Query query = session.createQuery("from Student where name=:name");
query.setParameter("name", "Raj");
In your case i guess the Entity name is Empdata(The object that represent the table)
And the field in the object is team(That has getter and setter in object)
Query query = session.createQuery("from Empdata where team=:teamParam");
query.setParameter("teamParam", "team1");
Related
I would like to group my query with Doctrine in Symfony3 in one of my repository but will not return any result. Mainly I think because of the attached relations to the entity.
the method looks as it follows
public function findAllByCurrentDemands($ids) {
$query = $this->createQueryBuilder('pt')
->select('pt')
->where('pt.id IN (:ids)')
//->groupBy('pt.demand_id')
->setParameter('ids', $ids)
->getQuery()->getResult();
dump($query);
die;
}
the raw sql example which is working in console and should be transformed to doctrine
SELECT demand_id
FROM ProductType
WHERE id IN (313,315,317,320,321,765,761,763,766)
GROUP BY demand_id;
How can I do this in a doctrine query like holding the attached relations?
Im newbie to web development,and I did some examples like get data from mysql db and show them in a jsp pages.(use CRUDRepository )
but in that way we can only show only one table data.
what should we do if we want to show combine two table data.
I found these while um searching,simply I m asking how we put a more complicated sql query to this.
public interface UserRepository extends JpaRepository<User, Long> {
#Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
#Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
if we can put that complicated query (like three tables or more) here,
should we create a new entity class according to query coloumns ??
then again is that work because actually there isn't any table like that.
To get more complex data from DB you can use projections, for example:
public interface UserProjection {
Long getId();
Long getFirstNameLen();
}
#Query("select u.id as id, LENGTH(u.firstName) as firstNameLen from User u where u.lastname like ?1%")
List<UserProjection> getProjections(String lastName, Sort sort);
Note that you should use aliases in the query that must match with getters in the projection (... as firstNameLen -> getFirstNameLen())
The same way you can get data from several (joined) entities.
If you have an entity with some associations, for example:
#Entity
public class User {
//...
#OneToMany
private List<Role> roles;
}
then you can use repository method to get the users and their roles data even without any projection, just for the main entity (User). Then Spring does the rest of the work itself:
#EntityGraph(attributePaths = "roles")
List<User> findByFirstNameContainingIgnoreCase(String firstName);
or the same with query:
#Query("select distinct u from User u left join fetch u.roles where upper(p.firstName) like concat('%', upper(?1), '%')")
List<User> findWithQuery(String firstName);
In this case all users will have their lists of roles are filled with data from the roles table.
(Note to use distinct in the query to prevent the result from duplicated records, more info see here.)
Useful resources:
Spring Data JPA - Reference Documentation
Query Creation
Repository query keywords
Projections
SpEL support in Spring Data JPA #Query definitions
Hibernate ORM User Guide
Associations
HQL and JPQL
JPQL Language Reference
I'm having an issue with inserting new rows into my MySQL database. I'm using Spring Boot with Spring Boot Data JPA.
Since MySQL doesn't support sequences, I decided to try and make my own sequence generator table. This is basically what I've done.
I created a sequences table that uses an auto increment field (used as my id's for my tables).
Created a function, sequences_nextvalue() which inserts into the sequences table and returns the new auto incremented id.
I then created triggers on each table that get triggered before insertion and replaces the id field with the result of calling sequences_nextvalue().
So this is working fine when inserting new rows. I'm getting unique ids across all tables. The issue I'm having is with my JPA entities.
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractBaseClass {
#Id
private Integer id = -1;
...
}
#Entity
public class ConcreteClass1 extends AbstractBaseClass {
...
}
#Entity
public class ConcreteClass2 extends AbstractBaseClass {
...
}
I want to be able to query from the abstract base class so I've placed my #Id column in that class and used #Entity with InheritanceType.TABLE_PER_CLASS. I've also initialized the id to -1 since an id is required to call save() from my spring crud repository.
After calling the save() function of my Spring data CrudRepository, the -1 for id properly gets replaced by the MySQL trigger but the resulting entity returned by save() doesn't return with the new id but instead retains the -1. After looking at the SQL logs, a select statement is not being called after insertion to get the new id but instead the original entity is being returned.
Is it possible to force Hibnerate to re-select the entity after insertion to get the new id when you're not using #GeneratedValue?
Any help is greatly appreciated.
Just wanted to provide an update on this question. Here is my solution.
Instead of creating MySQL TRIGGER's to replace the id on INSERT, I created a Hibernate IdentifierGenerator which executes a CallableStatement to get and return a new id.
My abstract base class now looks like this.
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractBaseClass {
#Id
#GenericGenerator(name="MyIdGenerator", strategy="com.sample.model.CustomIdGenerator" )
#GeneratedValue(generator="MyIdGenerator" )
private Integer id;
...
}
and my generator looks like this.
public class CustomIdGenerator implements IdentifierGenerator {
private Logger log = LoggerFactory.getLogger(CustomIdGenerator.class);
private static final String QUERY = "{? = call sequence_nextvalue()}";
#Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Integer id = null;
try {
Connection connection = session.connection();
CallableStatement statement = connection.prepareCall(QUERY);
statement.registerOutParameter(1, java.sql.Types.INTEGER);
statement.execute();
id = statement.getInt(1);
} catch(SQLException e) {
log.error("Error getting id", e);
throw new HibernateException(e);
}
return id;
}
}
And just for reference
The sequences table.
CREATE TABLE sequences (
id INT AUTO_INCREMENT PRIMARY KEY,
thread_id INT NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP
) ^;
The sequence_nextvalue function
CREATE FUNCTION sequence_nextvalue()
RETURNS INTEGER
NOT DETERMINISTIC
MODIFIES SQL DATA
BEGIN
DECLARE nextvalue INTEGER;
INSERT INTO sequences (thread_id) VALUE (CONNECTION_ID());
SELECT id FROM sequence_values ORDER BY created DESC LIMIT 1 INTO nextvalue;
RETURN nextvalue;
END ^;
I'm following this Tutorial. I have added another DAO where i'm retrieving the admin_roles table. The method looks like this
public List findAllAdminRoleByUserName(String userName) {
List<AdminRoles> users = new ArrayList<AdminRoles>();
Query hqlQuery = sessionFactory.getCurrentSession().createQuery("from admin_roles AdminRoles where AdminRoles.username = ?");
users = hqlQuery.setString(0, userName).list();
if (users.size() > 0) {
return users;
} else {
return null;
}
}
When I try to retrieve i'm getting the following error
HTTP Status 500 - Request processing failed; nested exception is org.hibernate.hql.internal.ast.QuerySyntaxException: admin_roles is not mapped [from admin_roles AdminRoles where AdminRoles.username = ?]
I am able to get values from the admin table mentioned in this tutorial, also I created some other tables from which i'm able to get values. But only this table is not being mapped. I also tried by changing the name of the table from "admin_roles" to adminroles(in the database and in code) I still get the same error.
The relevant class looks like this. Also the entity annotation is javax
#Entity
#Table(name = "admin_roles", uniqueConstraints = #UniqueConstraint(columnNames = { "role", "username" }))
public class AdminRoles{
Am I missing something? Thanks in advance
You're confusing tables and entities. Tables are a relational database concept. They're mapped to entities, which are Java classes. HQL uses entities. Always. Never tables.
BTW, the message is not "Table not mapped". It's "admin_roles is not mapped". And that's very different. HQL uses entities, so it expects admin_roles in your query to be a mapped entity. Not a table name. And you don't have any entity named admin_roles.
The query should be
select ar from AdminRoles ar where ar.username = ?
That assumes there is a mapped field/property named username in the AdminRoles entity class, of course.
You need to use the entity name in you query. Try like this:
"from AdminRoles AR where AR.username = ?"
I have 2 questions:
suppose we have one entity named class and another called student. each class has onetomany students.
public class Clas implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
private int id;
#OneToMany(cascade=CascadeType.ALL)
Collection<Student> students;
public clas(){
super();
}
..... getters and setters
}
q1: i get the exception there are no fields to be mapped, when adding any other column like String name, it works, but i don't need that field what can i do ?
q2: the ids is autogenerated, and i want to query all students in class c1, but i don't has the id of this class, how to do such query ?
iam working with mysql server glassfish v2.1 toplink jpa 1.0
Thanks
The student class must have a property named 'classID' (or whatever) that refers to the
Clas's id property. That should be annotated like #ManyToOne.
If that's done already by IDE, then check id generation strategy. For example, if you are using mysql, the primary key is auto_increment, then set th id's strategy to
GenerationType.AUTO and recompile. Tell me if any other errors shows up. :) .
ok. I think I understood you question. You may use NamedQueries written in Query Languages dependent on your library (in your case toplink) like EJB QL or HBQL. You can create Session Beans for querying.
public class ClassSessionBean {
#PersistenceContext(unitName="your PU name in persistence . xml")
private Entitymanager em;
publicClas selectByID(int id) throws NoResultException {
Query q = em.createQuery("select class from Class class where class.id=?");
q.setParameter(1, id);
Clas clas = q.getResultList();
return clas;
}
}
Note that the above code may contain syntax errors because I have not checked it anywhere.
Hope you find some help from this :) .