When I execute
#NamedQuery(name = "GroupsHasStudent.findByGroupsidGroups", query = "SELECT g FROM GroupsHasStudent g WHERE g.groupsHasStudentPK.groupsidGroups = :groupsidGroups"),
of GroupsHasStudent entity, the result is generated correct. But another NativeQuery
getEntityManager().
createNativeQuery(
"SELECT d.idDiscipline, d.name, gy.idGroupsYear, gy.year, g.idGroups "
+ "FROM Discipline d, Groupsyear gy, Groups g, GroupsHasStudent ghs "
+ "WHERE ghs.groupsHasStudentPK.groupsidGroups=2").
getResultList();
throws the Exception
Internal Exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Table 'mydb.groupshasstudent' doesn't exist
Actually I do don't have such table in db, but the correct name is *groups_has_student* which is specified in #Table:
(My entity:)
#Entity
#Table(name = "groups_has_student")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "GroupsHasStudent.findAll", query = "SELECT g FROM GroupsHasStudent g"),
#NamedQuery(name = "GroupsHasStudent.findByGroupsidGroups", query = "SELECT g FROM GroupsHasStudent g WHERE g.groupsHasStudentPK.groupsidGroups = :groupsidGroups"),
#NamedQuery(name = "GroupsHasStudent.findByStudentUserslogin", query = "SELECT g FROM GroupsHasStudent g WHERE g.groupsHasStudentPK.studentUserslogin = :studentUserslogin")})
public class GroupsHasStudent implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected GroupsHasStudentPK groupsHasStudentPK;
public GroupsHasStudent() {
}
And even when I rename table in mysql to groupshasstudent there is another Exception
Unknown column 'ghs.groupsHasStudentPK.studentUserslogin' in 'where clause'
І це сумно..
It's not a native (SQL) query, it's a JPQL query, therefore you should use createQuery() instead of createNativeQuery().
Related
I am currently trying to find out what the best pagination option is with EclipseLink and SQL Server.
I saw that for SQL Server there is no special support for pagination with EclipseLink. If I have the following data model, findAll creates a set of select (n + 1) for each subentity. That doesn't look efficient at first.
public class Foo {
#OneToMany( fetch = FetchType.LAZY )
private Set<Bar> bars = Sets.newHashSet();
}
public class Bar {
#OneToMany( fetch = FetchType.LAZY )
private Set<FooBar> fooBars = Sets.newHashSet();
}
public class FooBar {
String name;
}
So for every bar and fooBar there is a separate select.
Now I would like to discuss a few solutions. My current suggestions are. If a good possibility has been found, I can see how it is best implemented in spring data.
Chunking using Ids with IN
Query query = em.createQuery("SELECT f.id FROM Foo f ORDER BY f.id OFFSET 10 ROWS FETCH NEXT
10 ROWS ONLY");
List<Integer> ids = query.getResultList();
Query query = em.createQuery("SELECT DISTINCT f FROM foo f"
+ " LEFT JOIN FETCH f.bar bars "
+ " LEFT JOIN FETCH bar.fooBars foobars "
+ " WHERE t.id in (:ids) " )
query.setParameter("ids", ids.subList(5, 10));
List<Foo> foos = query.getResultList();
Using IN statement for every subselect (like hibernate) instead of single select
Using Batch with QueryHints IN or JOIN?
https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/q_batch.htm
Another possibility?
I have some question about Pessimistic Locking in SQL Server? Here are my classes and test scenario;
Entity class:
#Data
#Entity(name = "mapping")
#Table(
uniqueConstraints =
#UniqueConstraint(
name = "UQ_MappingEntity",
columnNames = {
Constants.DATA_TYPE_VALUE,
Constants.DATA_TYPE_NAMESPACE_INDEX,
Constants.TENANT_ID,
Constants.ASSET_TYPE_NAME
}
)
)
public class MappingEntity {
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
#Column(name = Constants.DATA_TYPE_VALUE)
private long dataTypeValue;
#Column(name = Constants.DATA_TYPE_NAMESPACE_INDEX)
private int dataTypeNamespaceIndex;
#Column(name = Constants.ASSET_TYPE_NAME)
private String assetTypeName;
#Column(name = Constants.TENANT_ID)
private String tenantId;
}
Repository class:
public interface MappingRepository extends JpaRepository<MappingEntity, String> {
#Lock(LockModeType.PESSIMISTIC_WRITE)
MappingEntity findMappingEntityWithLockByTenantIdAndAssetTypeName(
String tenantId, String assetTypeName);
}
Service code block:
#Transactional
public void deleteAspectType(String tenantId, String aspectTypeId) {
MappingEntity mappingEntity = mappingRepository.findMappingEntityWithLockByTenantIdAndAssetTypeName(tenantId, assetTypeName);
mappingRepository.delete(mappingEntity);
}
When I enable the hibernate logs. I see select query below.
select
mappingent0_.id as id1_1_,
mappingent0_.asset_type_name as asset_ty2_1_,
mappingent0_.data_type_namespace_index as data_typ3_1_,
mappingent0_.data_type_value as data_typ4_1_,
mappingent0_.tenant_id as tenant_i5_1_
from
mapping mappingent0_ with (updlock,
holdlock,
rowlock)
where
mappingent0_.tenant_id=?
and mappingent0_.asset_type_name=?
I have sent two delete request at the same time with same tenant_id but different asset_type_name;
Transaction-1: tenant_id = "testtenant", asset_type_name = "testname1"
Transaction-2: tenant_id = "testtenant", asset_type_name = "testname2"
Transaction-1 run select query and gets results, When Transaction-2 run select query it blocks. After Transaction-1 deletes and finishes the transaction, Transaction-2 get results and deletes.
I have two question;
What are the (updlock, holdlock, rowlock) use for? When I use these three same time, how does effect my query and transaction?
Why did Transaction-2 block when it run the query? Because Both transaction selected different rows.
Server inform error
HTTP Status 500 - Request processing failed; nested exception is
org.springframework.dao.TransientDataAccessResourceException:
StatementCallback; SQL [SELECT * FROM Accounts INNER JOIN Comment ON
Comment.Account_ID=Accounts.Account_ID WHERE Comment.Place_ID=3]; The
column name Accounts.Account_ID is not valid.; nested exception is
com.microsoft.sqlserver.jdbc.SQLServerException: The column name
Accounts.Account_ID is not valid.
This is my code in DAO
public List<LoadCommentDTO> loadComment(int placeId) {
String sql = "SELECT * FROM Accounts INNER JOIN Comment ON Comment.Account_ID=Accounts.Account_ID WHERE Comment.Place_ID="+ placeId ;
RowMapper<LoadCommentDTO> rowMapper = new CommentRowMapper();
List<LoadCommentDTO> listComment = jdbcTemplate.query(sql, rowMapper);
return listComment;
}
protected class CommentRowMapper implements RowMapper<LoadCommentDTO> {
#Override
public LoadCommentDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
LoadCommentDTO loadCommentDTO = new LoadCommentDTO();
CommentDTO commentDTO = new CommentDTO();
AccountDTO accountDTO = new AccountDTO();
accountDTO.setAccountID(rs.getInt("Accounts.Account_ID"));
accountDTO.setAvatar_path(rs.getString("Accounts.Avatar_path"));
accountDTO.setFirstname(rs.getString("Accounts.Firstname"));
accountDTO.setLastname(rs.getString("Accounts.Lastname"));
commentDTO.setAccount_Id(rs.getInt("Comment.Account_ID"));
commentDTO.setDescription(rs.getString("CommentDescription"));
commentDTO.setPlace_ID(rs.getInt("CommentPlace_ID"));
commentDTO.setC_Date(rs.getString("CommentC_Date"));
loadCommentDTO.setAccountDTO(accountDTO);
loadCommentDTO.setCommentDTO(commentDTO);
return loadCommentDTO;
}
}
I need to search all the usernames and for the application to print out all the usernames containting the search string. I think I have done this but when I execute searchByString(), I just get no results.
AbstractFacade
/* trying out a search function */
public List<T> searchByString(String string) {
System.out.println("in SearchByString");
return getEntityManager().createNamedQuery("Userdetails.findByUsername").setParameter("username", "%" + string + "%").getResultList();
}
Userdetails.java this is where the query is done
#Entity
#Table(name = "USERDETAILS")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Userdetails.findAll", query = "SELECT u FROM Userdetails u"),
#NamedQuery(name = "Userdetails.findById", query = "SELECT u FROM Userdetails u WHERE u.id = :id"),
#NamedQuery(name = "Userdetails.findByUsername", query = "SELECT u FROM Userdetails u WHERE u.username = :username")})
I can not get a filled list. I am wondering if the query is running right and retriving anything, so I want to be able to see what it retrieves when it is run, so I can look at why nothing gets displayed to the user.
Your query parameter looks like you want a like clause, but your named query uses =. Change
SELECT u FROM Userdetails u WHERE u.username = :username
to
SELECT u FROM Userdetails u WHERE u.username like :username
and it should work.
My Entity class
#Entity
class MasterStccycode{
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 3)
#Column(name = "CODE")
private String code;
#Size(max = 100)
#Column(name = "DESC")
private String desc;
}
my JPA Query
SELECT t.code, t.desc FROM MasterStccycode t
then I have this following exception
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'DESC'.
Error Code: 156
Call: SELECT CODE, DESC FROM master_stccycode
Query: ReportQuery(referenceClass=MasterStccycode sql="SELECT CODE, DESC FROM master_stccycode")
I know the solution is to wrap the DESC keyword with [] into [DESC] but how can I do this on JPA QL?
DESC is a reserved word on most databases. You should rename the field.
You could also quote the field, but just renaming it would be best.
#Column(name = "\"DESC\"")