JPA optimistic lock can't get the latest version - spring-data-jpa

I am using the JPA's optimistic lock with spring data jpa and using spring retry for ConcurrencyFailureException, but something occurs that i can't understand.
my test code just like below:
#Repository
public interface AccountRepo extends JpaRepository<Account, String>, JpaSpecificationExecutor<Account> {
#Lock(LockModeType.OPTIMISTIC)
#Query(value = "select a from Account a where a.id = :id")
Account findOne(#Param("id") String id);
}
--------------------------------------------------------------------
#Service
public class AccountService {
#Qualifier("accountRepo")
#Autowired
private AccountRepo accountRepo;
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
public Account saveOne(Account account){
return accountRepo.save(account);
}
public Account findOne(String id){
return accountRepo.findOne(id);
}
}
----------------------------------------------------------------------
#Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
#Retryable(value = {ConcurrencyFailureException.class}, backoff = #Backoff(delay = 3000))
public void testOptimistic(){
Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");
account.setHistoryIncome(new BigDecimal("3300"));
account.setTodayTotalIncome(new BigDecimal("3300"));
account.setTodayOnlineIncome(new BigDecimal("3300"));
account.setAvaliableAmount(new BigDecimal("3300"));
accountService.saveOne(account);
AccountOperRecord accountOperRecord = new AccountOperRecord();
accountOperRecord.setId(BuildNoUtil.buildAccountOperRecordId());
accountOperRecord.setTrxType(TrxTypeEnum.EXPENSE.name());
accountOperRecord.setAvaliableAmount(account.getAvaliableAmount());
accountOperRecord.setOperAmount(new BigDecimal("100"));
accountOperRecord.setOrderId("4028b8815c813d64015c813e17f50000");
accountOperRecord.setOutTradeNo("2015061121001004400068549373");
accountOperRecord.setAccountId("abee19e08d3d4ee79d9f831c3ed78344");
accountOperRecordService.saveOne(accountOperRecord);
}
----------------------------------------------------------------------
#Controller
public class TestController extends BaseController {
#RequestMapping(value = "testOptimistic")
#ResponseBody
public JSONObject testOptimisticLock(){
JSONObject result = new JSONObject();
conjunctionService.testOptimistic();
result.put("code", "success");
return result;
}
}
i added a breakpoint at Account account = accountService.findOne("abee19e08d3d4ee79d9f831c3ed78344");, then i run a transaction in mysql to change the version of Account.
After that, the testOptimistic method throws the ConcurrencyFailureException and the method retried, in my opinion, it will success the next time but it failed again, finally it success at the third time, i just can not understand.
the logs of Hibernate SQL showed below
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select account0_.id as id1_0_, account0_.create_time as create_t2_0_, account0_.creater as creater3_0_, account0_.edit_time as edit_tim4_0_, account0_.editor as editor5_0_, account0_.remark as remark6_0_, account0_.address as address7_0_, account0_.avaliable_amount as avaliabl8_0_, account0_.email as email9_0_, account0_.history_expense as history10_0_, account0_.history_income as history11_0_, account0_.merchant_name as merchan12_0_, account0_.name as name13_0_, account0_.phone as phone14_0_, account0_.settled_amount as settled15_0_, account0_.settling_amount as settlin16_0_, account0_.splited_amount as splited17_0_, account0_.today_offline_income as today_o18_0_, account0_.today_online_income as today_o19_0_, account0_.today_total_income as today_t20_0_, account0_.version as version21_0_ from account account0_ where account0_.id=?
Hibernate: select accountope0_.id as id1_1_0_, accountope0_.account_id as account_2_1_0_, accountope0_.avaliable_amount as avaliabl3_1_0_, accountope0_.oper_amount as oper_amo4_1_0_, accountope0_.order_id as order_id5_1_0_, accountope0_.out_trade_no as out_trad6_1_0_, accountope0_.remit_id as remit_id7_1_0_, accountope0_.settle_id as settle_i8_1_0_, accountope0_.split_batch_id as split_ba9_1_0_, accountope0_.trx_type as trx_typ10_1_0_ from account_oper_record accountope0_ where accountope0_.id=?
Hibernate: insert into account_oper_record (account_id, avaliable_amount, oper_amount, order_id, out_trade_no, remit_id, settle_id, split_batch_id, trx_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update account set avaliable_amount=?, history_income=?, today_online_income=?, today_total_income=?, version=? where id=? and version=?
Hibernate: select version from account where id =?
Hibernate: select version from account where id =?
you can see that select version from account where id =? execute two times at the third time, anyone can explain this?!
Thank you very much!

Related

Spring batch: items are read again before write when using cursor

I have a spring batch with a step that:
read from table all message in "SCHEDULED" status
process message
update message status to "SENT" or other status according to process result
Using RepositoryItemReader i had the problem that updating items state messed up pagination, so i ended up using JpaCursorItemReader.
Everything goes fine, but now all the items are read again from DB before the update phase (this not happens when using RepositoryItemReader).
Here is my relevant code:
#Autowired
private MessageSenderProcessor messageSenderProcessor;
#Autowired
private GovioMessagesRepository govioMessagesRepository;
public Step getProfileStep(){
return steps.get("getProfileStep")
.<GovioMessageEntity, GovioMessageEntity>chunk(10)
.reader(expiredScheduledDateMessageReader())
.processor(this.messageSenderProcessor)
.writer(messageWriter())
.build();
}
private RepositoryItemWriter<GovioMessageEntity> messageWriter() {
final RepositoryItemWriter<GovioMessageEntity> repositoryItemWriter = new RepositoryItemWriter<>();
repositoryItemWriter.setRepository(govioMessagesRepository);
repositoryItemWriter.setMethodName("save");
return repositoryItemWriter;
}
private ItemReader<GovioMessageEntity> expiredScheduledDateMessageCursor() {
JpaCursorItemReader<GovioMessageEntity> itemReader = new JpaCursorItemReader<>();
itemReader.setQueryString("SELECT msg FROM GovioMessageEntity msg WHERE msg.status = :status AND msg.scheduledExpeditionDate < :now");
itemReader.setEntityManagerFactory(entityManager.getEntityManagerFactory());
itemReader.setSaveState(true);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("status", Status.SCHEDULED);
parameters.put("now", LocalDateTime.now());
itemReader.setParameterValues(parameters);
return itemReader;
}
Here an extract of execution log:
Hibernate: select goviomessa0_.id as id1_0_0_, govioservi1_.id as id1_1_1_, goviomessa0_.amount as amount2_0_0_, goviomessa0_.appio_message_id as appio_me3_0_0_, goviomessa0_.creation_date as creation4_0_0_, goviomessa0_.expedition_date as expediti5_0_0_, goviomessa0_.id_govio_service_instance as id_govi15_0_0_, goviomessa0_.invalid_after_due_date as invalid_6_0_0_, goviomessa0_.last_update_status as last_upd7_0_0_, goviomessa0_.markdown as markdown8_0_0_, goviomessa0_.notice_number as notice_n9_0_0_, goviomessa0_.payee as payee10_0_0_, goviomessa0_.scheduled_expedition_date as schedul11_0_0_, goviomessa0_.status as status12_0_0_, goviomessa0_.subject as subject13_0_0_, goviomessa0_.taxcode as taxcode14_0_0_ from govio_messages goviomessa0_ where goviomessa0_.status=? and goviomessa0_.scheduled_expedition_date<?
2022-11-07 10:03:06,990 INFO [spring_batch_msgsender1] it.govio.msgsender.step.GetProfileProcessor: Sending msg 1
2022-11-07 10:03:06,990 INFO [spring_batch_msgsender2] it.govio.msgsender.step.GetProfileProcessor: Sending msg 2
2022-11-07 10:03:06,990 INFO [spring_batch_msgsender3] it.govio.msgsender.step.GetProfileProcessor: Sending msg 3
....
2022-11-07 10:03:07,171 INFO [spring_batch_msgsender1] it.govio.msgsender.step.GetProfileProcessor: Message sent.
2022-11-07 10:03:07,171 INFO [spring_batch_msgsender2] it.govio.msgsender.step.GetProfileProcessor: Message sent.
2022-11-07 10:03:07,220 INFO [spring_batch_msgsender3]
....
Hibernate: select goviomessa0_.id as id1_0_0_, goviomessa0_.amount as amount2_0_0_, goviomessa0_.appio_message_id as appio_me3_0_0_, goviomessa0_.creation_date as creation4_0_0_, goviomessa0_.expedition_date as expediti5_0_0_, goviomessa0_.id_govio_service_instance as id_govi15_0_0_, goviomessa0_.invalid_after_due_date as invalid_6_0_0_, goviomessa0_.last_update_status as last_upd7_0_0_, goviomessa0_.markdown as markdown8_0_0_, goviomessa0_.notice_number as notice_n9_0_0_, goviomessa0_.payee as payee10_0_0_, goviomessa0_.scheduled_expedition_date as schedul11_0_0_, goviomessa0_.status as status12_0_0_, goviomessa0_.subject as subject13_0_0_, goviomessa0_.taxcode as taxcode14_0_0_ from govio_messages goviomessa0_ where goviomessa0_.id=?
Hibernate: select goviomessa0_.id as id1_0_0_, goviomessa0_.amount as amount2_0_0_, goviomessa0_.appio_message_id as appio_me3_0_0_, goviomessa0_.creation_date as creation4_0_0_, goviomessa0_.expedition_date as expediti5_0_0_, goviomessa0_.id_govio_service_instance as id_govi15_0_0_, goviomessa0_.invalid_after_due_date as invalid_6_0_0_, goviomessa0_.last_update_status as last_upd7_0_0_, goviomessa0_.markdown as markdown8_0_0_, goviomessa0_.notice_number as notice_n9_0_0_, goviomessa0_.payee as payee10_0_0_, goviomessa0_.scheduled_expedition_date as schedul11_0_0_, goviomessa0_.status as status12_0_0_, goviomessa0_.subject as subject13_0_0_, goviomessa0_.taxcode as taxcode14_0_0_ from govio_messages goviomessa0_ where goviomessa0_.id=?
....
Hibernate: update govio_messages set amount=?, appio_message_id=?, creation_date=?, expedition_date=?, id_govio_service_instance=?, invalid_after_due_date=?, last_update_status=?, markdown=?, notice_number=?, payee=?, scheduled_expedition_date=?, status=?, subject=?, taxcode=? where id=?
Hibernate: update govio_messages set amount=?, appio_message_id=?, creation_date=?, expedition_date=?, id_govio_service_instance=?, invalid_after_due_date=?, last_update_status=?, markdown=?, notice_number=?, payee=?, scheduled_expedition_date=?, status=?, subject=?, taxcode=? where id=?
...
So i have those questions:
Why the item is read again after process phase when using cursor?
Can i avoid this?
CursorItemReader as item reader is the right choice for my use case?

Keycloak addUser inside custom Authenticator getting error

Here is my not finished source that will do some "checks" then addUser if not exist,
Currently I'm testing simply adding new user here is my writings
public void authenticate(AuthenticationFlowContext context) {
KeycloakSession session = context.getSession();
RealmModel realm = context.getRealm();
String username = "hello";
UserProvider users = session.userLocalStorage();
UserModel user = users.getUserByUsername(realm,username);
if (user == null) {
logger.infof("addingUser");
user = session.users().addUser(realm,username);
logger.infof("isEnabled()");
user.setEnabled(true);
user.setEmail("mail#mail.com");
user.setEmailVerified(true);
}
context.setUser(user);
context.success();
}
with this source when I try to login for the first time, it gets me error but user is created.
Then if I try to login for the second time, it logs in successfully (shows me personal page)
06:05:12,633 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-8)
Unique index or primary
key violation: "UK_RU8TT6T700S9V50BU18WS5HA6_INDEX_B ON PUBLIC.USER_ENTITY(REALM_ID,
USERNAME) VALUES ('Customer', 'hello', 5)"; SQL statement:
2021-11-12T06:05:12.634069100Z insert into USER_ENTITY (CREATED_TIMESTAMP, EMAIL,
EMAIL_CONSTRAINT, EMAIL_VERIFIED, ENABLED, FEDERATION_LINK,
FIRST_NAME, LAST_NAME, NOT_BEFORE, REALM_ID, SERVICE_ACCOUNT_CLIENT_LINK, USERNAME,
ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23505-197]
2021-11-12T06:05:12.647493900Z
Additional information logs show me output twice for example
2021-11-12T06:05:12.610917800Z 06:05:12,610 INFO [class name] (default task-6) addingUser
2021-11-12T06:05:12.615587600Z 06:05:12,615 INFO [class name] (default task-8) addingUser
task 6 reaches log output logger.infof("isEnabled()");
task 8 not

Can't add a claim with ASP.NET Core and identity

I try to add a custom claim to an existing Identity user but I get an exception at run-time:
Npgsql.PostgresException: 23502: null value in column "Id" violates not-null constraint
Help!
What I did. I've created a simple web app on windows using the following command line
dotnet new mvc --auth Individual --framework netcoreapp1.1
I made changes found here to make the app use PostgreSQL as the database back-end. The created default webapp works fine. I can register as a new user, login, log out, etc...
Then I modified the Test method of the Home controller (I know the exceptions are ugly):
[Authorize]
public async Task<IActionResult> Test()
{
var user = await GetCurrentUserAsync();
if (user == null) {
_logger.LogWarning("User is null.");
throw new Exception("Not logged in");
}
_logger.LogWarning("User: {0}, {1}", user.Email, user);
var claim = new Claim("TestClaimType", "TestClaimValue");
IdentityResult idRes = IdentityResult.Failed();
if (_userManager.SupportsUserClaim) {
idRes = await _userManager.AddClaimAsync(user, claim); <------- Adding the claim
}
_logger.LogWarning("Return from adding claim");
if (idRes != IdentityResult.Success) {
throw new Exception("Failed to add claim.");
}
return View();
}
After logging in, I trigger the Test method and get the following logging (the PostgresException is near the end):
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5000/Home/Test
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[3]
HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Identity.Application.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful for user: mark#mark.com.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method AlumniConnect.Controllers.HomeController.Test (AlumniConnect) with arguments ((null)) - ModelState is Valid
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (1ms) [Parameters=[#__get_Item_0='?'], CommandType='Text', CommandTimeout='30']
SELECT "e"."Id", "e"."AccessFailedCount", "e"."ConcurrencyStamp", "e"."Email", "e"."EmailConfirmed", "e"."LockoutEnabled", "e"."LockoutEnd", "e"."NormalizedEmail", "e"."NormalizedUserName", "e"."PasswordHash", "e"."PhoneNumber", "e"."PhoneNumberConfirmed", "e"."SecurityStamp", "e"."TwoFactorEnabled", "e"."UserName"
FROM "AspNetUsers" AS "e"
WHERE "e"."Id" = #__get_Item_0
LIMIT 1
warn: AlumniConnect.Controllers.HomeController[0]
User: mark#mark.com, mark#mark.com
warn: AlumniConnect.Controllers.HomeController[0]
User: mark#mark.com, mark#mark.com
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (4ms) [Parameters=[#__normalizedUserName_0='?'], CommandType='Text', CommandTimeout='30']
SELECT "u"."Id", "u"."AccessFailedCount", "u"."ConcurrencyStamp", "u"."Email", "u"."EmailConfirmed", "u"."LockoutEnabled", "u"."LockoutEnd", "u"."NormalizedEmail", "u"."NormalizedUserName", "u"."PasswordHash", "u"."PhoneNumber", "u"."PhoneNumberConfirmed", "u"."SecurityStamp", "u"."TwoFactorEnabled", "u"."UserName"
FROM "AspNetUsers" AS "u"
WHERE "u"."NormalizedUserName" = #__normalizedUserName_0
LIMIT 1
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (33ms) [Parameters=[#p0='?', #p1='?', #p2='?', #p17='?', #p3='?', #p4='?', #p18='?', #p5='?', #p6='?', #p7='?', #p8='?', #p9='?', #p10='?', #p11='?', #p12='?', #p13='?', #p14='?', #p15='?', #p16='?'], CommandType='Text', CommandTimeout='30']
INSERT INTO "AspNetUserClaims" ("ClaimType", "ClaimValue", "UserId")
VALUES (#p0, #p1, #p2)
RETURNING "Id";
UPDATE "AspNetUsers" SET "AccessFailedCount" = #p3, "ConcurrencyStamp" = #p4, "Email" = #p5, "EmailConfirmed" = #p6, "LockoutEnabled" = #p7, "LockoutEnd" = #p8, "NormalizedEmail" = #p9, "NormalizedUserName" = #p10, "PasswordHash" = #p11, "PhoneNumber" = #p12, "PhoneNumberConfirmed" = #p13, "SecurityStamp" = #p14, "TwoFactorEnabled" = #p15, "UserName" = #p16
WHERE "Id" = #p17 AND "ConcurrencyStamp" = #p18;
fail: Microsoft.EntityFrameworkCore.DbContext[1]
An exception occurred in the database while saving changes.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Npgsql.PostgresException: 23502: null value in column "Id" violates not-null constraint
at Npgsql.NpgsqlConnector.<DoReadMessageAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
There's lots of logging more but it doesn't seem to add new information. I see the same exception mentioned multiple times throughout the log.
What can I do? Is this a PostgreSQL specific issue? Am I trying to add a claim in the wrong way?
Thanks!
In the migration for Identity, all tables that have a generated Integer id have an annotation for adding auto generation of this id. This annotation is SQL Server specific, like .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
The fix for this is to add a Postgres specific annotation to the migration: .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn). In older versions of Npgsql.EntityFrameworkCore.PostgreSQL it could be that you need to use .Annotation("Npgsql:ValueGeneratedOnAdd", true).
The part of the migration for creating the AspNetRoleClaims table will then look like:
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
It appears that when the Claim is added to the database, the 'RETURNING "Id"' clause of the SQL statement suggests the ID is returned. However, the table does not have an auto incrementing ID column.
I verified this by following the instructions from Adding 'serial' to existing column in Postgres.
The problem is now of course that this should have been taken care of automatically...

org.postgresql.util.PSQLException: No results returned by the query

hey everyone am trying to insert data in a table using #Query annotation in my spring boot app am getting a postgres Exception :
org.postgresql.util.PSQLException: No results returned by the query
this is my code :
this is the repository
#Query(value="INSERT INTO \"FCT_BY_DEV\"(\"IdDev\", \"IdFonction\") VALUES (?, ?) ",nativeQuery=true)
public String isertfonctionstodev(int dev,int fonction);
this is the controller :
#RequestMapping(value="/function/insert", method = RequestMethod.POST)
public String insererfonctions (int dev,int fonction){
System.out.println("dev="+dev+"fonction="+fonction);
fonctionRepository.isertfonctionstodev(dev, fonction);
System.out.println("********");
return "aaa";
}
am using this service by $http in angularJs
$http.post("/function/insert?dev="+$scope.id+"&fonction="+$scope.idf);
and finaly this is the server log
dev=16006fonction=14
Hibernate: INSERT INTO "FCT_BY_DEV"("IdDev", "IdFonction") VALUES (?, ?)
2016-04-27 16:52:03.204 WARN 7036 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 02000
2016-04-27 16:52:03.204 ERROR 7036 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Aucun résultat retourné par la requête.
the data is correct and i tried the same query with the same value and it worked why posgres is generating this exception and how can i fixed , thanks to any help
I think modifying queries must be annotared with an extra
#Modifying
This should solve your issue:
#Transactional
#Modifying(clearAutomatically = true)
#Query(value="update policy.tbl_policy set ac_status = 'INACTIVE' where pol_id = :policyId and version_no = :version_no and ac_status = 'ACTIVE'", nativeQuery=true)
public void updateExistingRowbyId(#Param("policyId") Long pol_id, #Param("version_no") Long version_no);
Without #Transactional annotation, following errors may occur:
javax.persistence.TransactionRequiredException: Executing an update/delete query

optional include with entity framework

I'm working on a manager. Depending on the conditions some include must be enforced in order to get eager loading. But sometime I don't want all the data so the includes should not be applied.
This is what I've got so far.
//INFO : public partial class Entities : DbContext
var Database = new Entities();
var result = Database.Department;
if (includeHospitalEmployee) { result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result.Include(a => a.QuickScan); }
return result;
This doesn't work. The includes aren't loaded, although the includebooleans are set to true. Query results in;
SELECT
[Extent1].[Code] AS [Code],
[Extent1].[Discipline] AS [Discipline],
[Extent1].[FinancialCode] AS [FinancialCode],
[Extent1].[Name] AS [Name],
[Extent1].[DepartmentManagerId] AS [DepartmentManagerId],
[Extent1].[Show] AS [Show],
[Extent1].[Id] AS [Id]
FROM [dbo].[Department] AS [Extent1]
But strange enough if i do this, all include are working
//INFO : public partial class Entities : DbContext
var Database = new Entities();
var result = this.businessManagersFactory.Database.Department.Include(a => a.QuickScan);;
if (includeHospitalEmployee) { result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result.Include(a => a.QuickScan); }
return result;
see the query
SELECT
[Project1].[C1] AS [C1],
[Project1].[Code] AS [Code],
[Project1].[Discipline] AS [Discipline],
[Project1].[FinancialCode] AS [FinancialCode],
[Project1].[Name] AS [Name],
[Project1].[DepartmentManagerId] AS [DepartmentManagerId],
[Project1].[Show] AS [Show],
[Project1].[Id] AS [Id],
[Project1].[C2] AS [C2],
[Project1].[Id1] AS [Id1],
[Project1].[StartDateTime] AS [StartDateTime],
[Project1].[EndDateTime] AS [EndDateTime],
[Project1].[Shared] AS [Shared],
[Project1].[ScanStatus] AS [ScanStatus],
[Project1].[Title] AS [Title],
[Project1].[Count] AS [Count],
[Project1].[Comment] AS [Comment],
[Project1].[HospitalEmployeeId] AS [HospitalEmployeeId],
[Project1].[DepartmentId] AS [DepartmentId]
FROM ( SELECT
[Extent1].[Code] AS [Code],
[Extent1].[Discipline] AS [Discipline],
[Extent1].[FinancialCode] AS [FinancialCode],
[Extent1].[Name] AS [Name],
[Extent1].[DepartmentManagerId] AS [DepartmentManagerId],
[Extent1].[Show] AS [Show],
[Extent1].[Id] AS [Id],
1 AS [C1],
[Extent2].[Id] AS [Id1],
[Extent2].[StartDateTime] AS [StartDateTime],
[Extent2].[EndDateTime] AS [EndDateTime],
[Extent2].[Shared] AS [Shared],
[Extent2].[ScanStatus] AS [ScanStatus],
[Extent2].[Title] AS [Title],
[Extent2].[Count] AS [Count],
[Extent2].[Comment] AS [Comment],
[Extent2].[HospitalEmployeeId] AS [HospitalEmployeeId],
[Extent2].[DepartmentId] AS [DepartmentId],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM [dbo].[Department] AS [Extent1]
LEFT OUTER JOIN [dbo].[QuickScan] AS [Extent2] ON [Extent1].[Code] = [Extent2].[DepartmentId]
) AS [Project1]
ORDER BY [Project1].[Code] ASC, [Project1].[C2] ASC
Why is this behaviour and how to get it working properly?
regards
I don't have access to Visual Studio to confirm but you will probably find that assigning the return from the call to Include will sort it - it will be something like a QueryObject that implements IQueryable
var Database = new Entities();
IQueryable<Department> result = Database.Departments;
if (includeHospitalEmployee) { result = result.Include(a => a.HospitalEmployee); }
if (includeQuickScans) { result = result.Include(a => a.QuickScan); }
return result;