I tried to write a udf function to calculate my data. In the trino's docs, I knew I should to write a function plugin and I succeed to execute my udf aggregate function sql.
But when I write sql with aggregate function and window function, the sql executed failed.
The error log is com.google.common.util.concurrent.ExecutionError: java.lang.NoClassDefFoundError: com/example/ListState.
I think I may implement the interface about the window function.
The ListState.java file code
#AccumulatorStateMetadata(stateSerializerClass = ListStateSerializer.class, stateFactoryClass = ListStateFactory.class)
public interface ListState extends AccumulatorState {
List<String> getList();
void setList(List<String> value);
}
The ListStateSerializer file code
public class ListStateSerializer implements AccumulatorStateSerializer<ListState>
{
#Override
public Type getSerializedType() {
return VARCHAR;
}
#Override
public void serialize(ListState state, BlockBuilder out) {
if (state.getList() == null) {
out.appendNull();
return;
}
String value = String.join(",", state.getList());
VARCHAR.writeSlice(out, Slices.utf8Slice(value));
}
#Override
public void deserialize(Block block, int index, ListState state) {
String value = VARCHAR.getSlice(block, index).toStringUtf8();
List<String> list = Arrays.asList(value.split(","));
state.setList(list);
}
}
The ListStateFactory file code
public class ListStateFactory implements AccumulatorStateFactory<ListState> {
public static final class SingleListState implements ListState {
private List<String> list = new ArrayList<>();
#Override
public List<String> getList() {
return list;
}
#Override
public void setList(List<String> value) {
list = value;
}
#Override
public long getEstimatedSize() {
if (list == null) {
return 0;
}
return list.size();
}
}
public static class GroupedListState implements GroupedAccumulatorState, ListState {
private final ObjectBigArray<List<String>> container = new ObjectBigArray<>();
private long groupId;
#Override
public List<String> getList() {
return container.get(groupId);
}
#Override
public void setList(List<String> value) {
container.set(groupId, value);
}
#Override
public void setGroupId(long groupId) {
this.groupId = groupId;
if (this.getList() == null) {
this.setList(new ArrayList<String>());
}
}
#Override
public void ensureCapacity(long size) {
container.ensureCapacity(size);
}
#Override
public long getEstimatedSize() {
return container.sizeOf();
}
}
#Override
public ListState createSingleState() {
return new SingleListState();
}
#Override
public ListState createGroupedState() {
return new GroupedListState();
}
}
Thanks for help!!!!
And I found the WindowAccumulator class in the trino source code. But I don't know how to use it.
How to create a aggregate function for window function?
I have all my tests pass except this line in the first test
verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
see code below.
package com.revature.services;
public class ReimbursementServiceTest {
private static ReimbursementService reimbursementService;
private static ReimbursementDAO reimbursementDAO;
private Reimbursement REIMBURSEMENT_TO_PROCESS;
private Reimbursement GENERIC_REIMBURSEMENT_1;
private Optional<Reimbursement>
GENERIC_REIMBURSEMENT_2;
private List<Reimbursement> GENERIC_ALL_PENDING_REIMBURSEMENTS;
private User GENERIC_EMPLOYEE_1;
private User GENERIC_FINANCE_MANAGER_1;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
reimbursementDAO=mock(ReimbursementDAO.class);//(IReimbursementDAO.class);
reimbursementService = new ReimbursementService(reimbursementDAO);
//reimbursementDAO=new ReimbursementDAO();
}
#Before
public void setUp() throws Exception {
GENERIC_EMPLOYEE_1 = new User(1, "genericEmployee1", "genericPassword", Role.EMPLOYEE);
GENERIC_FINANCE_MANAGER_1 = new User(1, "genericManager1", "genericPassword", Role.FINANCE_MANAGER);
REIMBURSEMENT_TO_PROCESS = new Reimbursement(2, Status.PENDING, GENERIC_EMPLOYEE_1, null, 150.00);
GENERIC_REIMBURSEMENT_1 = new Reimbursement(1, Status.PENDING, GENERIC_EMPLOYEE_1, null, 100.00);
GENERIC_REIMBURSEMENT_2 = Optional.ofNullable(new Reimbursement(2, Status.APPROVED, GENERIC_EMPLOYEE_1,
GENERIC_FINANCE_MANAGER_1, 150.00));
GENERIC_ALL_PENDING_REIMBURSEMENTS = new ArrayList<Reimbursement>();
GENERIC_ALL_PENDING_REIMBURSEMENTS.add(GENERIC_REIMBURSEMENT_1);
}
#Test
public void testProcessPassesWhenUserIsFinanceManagerAndReimbursementExistsAndUpdateSuccessful()
throws Exception{
when(reimbursementDAO.getById(anyInt())).thenReturn(Optional.of(GENERIC_REIMBURSEMENT_1));
when(reimbursementDAO.update(any())).thenReturn(GENERIC_REIMBURSEMENT_2);
assertEquals(GENERIC_REIMBURSEMENT_2,
reimbursementService.process(REIMBURSEMENT_TO_PROCESS, Status.APPROVED,
GENERIC_FINANCE_MANAGER_1));
//verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
verify(reimbursementDAO).update(REIMBURSEMENT_TO_PROCESS);
}
#Test
public void testGetReimbursementByStatusPassesWhenReimbursementsAreSuccessfullyReturned() {
when(reimbursementDAO.getBystatus(any())).thenReturn(GENERIC_ALL_PENDING_REIMBURSEMENTS);
assertEquals(GENERIC_ALL_PENDING_REIMBURSEMENTS,
reimbursementService.getReimbursementsByStatus(Status.PENDING));
verify(reimbursementDAO).getBystatus(Status.PENDING);
}
}
public class ReimbursementDAO extends AbstractReimbursement
{
public Optional< Reimbursement> getById(int id) {
try(Connection conn = ConnectionFactory.getConnection())
{
String sql="select * from ers_reimbursements where reimb_id=?;";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setInt(1,id);
ResultSet rs= ps.executeQuery();
Reimbursement reimb=null;
UserService usrv=new UserService();
//reimb_id ,amount, submitted,resolved,description,author,receipt ,resolver,status,reimb_type
while(rs.next())
{
int reid=rs.getInt("reimb_id");
double ramount=rs.getInt("reimb_amount");
int res=rs.getInt( "resolver");
User resolver=null;
String description=rs.getString("description");
User rauthor= usrv.getUserById( rs.getInt("author")).get();
if(res>0)
{ resolver= usrv.getUserById(res).get(); }
int rstatus= rs.getInt("reimb_status");
Status r_status=Status.values()[--rstatus];
int reimb_type= rs.getInt("reimb_type");
ReimbType retype=ReimbType.values()[--reimb_type];
User oth=rauthor;
User re=resolver;
reimb=new Reimbursement(reid, r_status,oth,re,ramount);
return Optional.ofNullable(reimb);
}
}catch(SQLException e) { e.printStackTrace();};
return Optional.empty();
}
public List<Reimbursement> getBystatus(Status status) {
try(Connection conn = ConnectionFactory.getConnection())
{
String sql="select * from ers_reimbursements where reimb_status=?;";
PreparedStatement ps=conn.prepareStatement(sql);//,Statement.RETURN_GENERATED_KEYS);
int sta_id= status.ordinal()+1;
ps.setInt(1,sta_id);
ResultSet rs= ps.executeQuery();
Reimbursement reimb=null;
List<Reimbursement> reimbList=new ArrayList<Reimbursement>();
IUserService usrv=new UserService();
//reimb_id ,amount, submitted,resolved,description,author,receipt ,resolver,status,reimb_type
while(rs.next())
{
//int id, Status status, User author, User resolver, double amount
int reid=rs.getInt("reimb_id");
double ramount=rs.getInt("reimb_amount");
Optional<User> rauthor= usrv.getUserById( rs.getInt("author"));
User oth=null;
if(rauthor.isPresent())
{ oth=rauthor.get(); }
int resol=rs.getInt( "resolver");
Optional<User> resolver= usrv.getUserById(resol);
User re=null;
if(resolver.isPresent())
{ re=resolver.get(); }
else {re=null;}
int rstatus= rs.getInt("reimb_status");
Status r_status=Status.values()[--rstatus];//.PENDING;
int reimb_type= rs.getInt("reimb_type");
ReimbType retype=ReimbType.values()[--reimb_type];//.TRAVEL;
reimb=new Reimbursement(reid, r_status,oth,re,ramount);
reimbList.add(reimb);
}
return reimbList;
}catch(SQLException e) { e.printStackTrace();};
return null;
}
public Optional<Reimbursement> update(Reimbursement unprocessedReimbursement) {
try(Connection conn=ConnectionFactory.getConnection()) {
String sql="update ers_reimbursements set reimb_status=?,"
+ " resolver=?, resolved=? where reimb_id=?;";
PreparedStatement ps=conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
int id=unprocessedReimbursement.getId();
Status st=unprocessedReimbursement.getStatus();
ps.setObject(1,st);
ps.setInt(2,unprocessedReimbursement.getResolver().getId());
ps.setObject(3, LocalDateTime.now());
ps.setInt(4,id);
ps.executeUpdate();
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
int reimid=generatedKeys.getInt(1);
Optional<Reimbursement> reim=getById(reimid);
System.out.println("Reimb " + reim.get()+ " upLocalTimed!");
return reim;
}
}catch(SQLException e) {};
}catch(SQLException e) { e.printStackTrace();}
return Optional.empty();
}
}
public class ReimbursementService{
{
private final ReimbursementDAO reimbDao;
public ReimbursementService() {
this(new ReimbursementDAO());
}
public ReimbursementService(ReimbursementDAO userDAO2) {
this.reimbDao = userDAO2;
}
public Optional< Reimbursement> process(Reimbursement unprocessedReimbursement,
Status finalStatus, User resolver) throws Exception{
if (!resolver.getRole().equals(Role.FINANCE_MANAGER)) {
throw new RegistrationUnsuccessfulException("Resolver must be Finance Manager ");
}
// List<Reimbursement> l=DAO.getByStatus(Status.PENDING);
if(unprocessedReimbursement.getId()==0)
{ throw new Exception(" reimbursement not found"); }
if(unprocessedReimbursement.getStatus().equals(Status.PENDING))
{
unprocessedReimbursement.setResolver(resolver);
unprocessedReimbursement.setStatus(finalStatus);
Optional<Reimbursement> reimb=this.reimbDao.update(unprocessedReimbursement );
if(reimb.isPresent())
{ return reimb; }
else { throw new Exception("unsuccessful update");}
}
return Optional.ofNullable(null);
}
}
The verification
verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
fails because your service does not call the getById() method of your DAO.
It happens that your real DAO's update() method calls its own getById() method, but in your test you are using a mock DAO, where all functionality has been stubbed out. The update() method of the mock DAO does nothing more than return GENERIC_REIMBURSEMENT_2 because that's what your test sets it up to do.
Unable to insert into child table in a single transaction using springboot and jdbctemplate.
Controller:
#RequestMapping(value = "/addUser", method = RequestMethod.POST)
public Response addUser(#RequestBody UserVo userVo) throws Exception
{
service.addUserRecord(userVo);
}
Service Layer:
#Autowired
private Dao dao;
#Transactional(readOnly = false)
public void addUserRecord(#RequestBody UserVo userVo) throws Exception
{
int parentSeqNo = dao.addUser();
int result = dao.addUserDetails(parentSeqNo, list);
}
DAOImple class:
#Autowired
private JdbcTemplate jdbcTemplate;
public int addUser()
{
try
{
String sql = "INSERT INTO user_table() VALUES (?,?,?,?,?) ";
jdbcTemplate.update(sql,....);
return seqNo;
}
catch(Exception e)
{
e.printStackTrace();
throw e;
}
}
public void addUserDetails(String seqNo, List<String> list){
String sql="insert into user_details_table values(?,?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException {
String img = list.get(i);
ps.setString(1, seqNo);
ps.setString(2, img);
}
public int getBatchSize() {
return list.size();
}
});
return;
}
Issue/Error:
ORA-02291: integrity constraint (FK3) violated - parent key not found; nested exception is java.sql.SQLIntegrityConstraintViolationException:
Database tables and constraints are looks good and tried to insert using sql editor, just working fine. While testing from postman tool, getting parent key not found exception. Greatly appreciated for any suggestions on this issue.
getJdbcTemplate().query(getFileContentSql, new RowMapper<Void>() {
public void mapRow(ResultSet rs, int rowNum) throws SQLException {
OracleLobHandler lobHandler = new OracleLobHandler();
InputStream inputStream = lobHandler.getBlobAsBinaryStream(rs, "file_content");
ExlImporter importer = new ExlBOMImporter(inputStream);
importer.process();
}
}, fileId);
Please tell me what is Void ?
Note : V is capital.
Form the javadoc:
The Void class is an uninstantiable placeholder class to hold a
reference to the Class object representing the Java keyword void.
Hi My thread class is showing null pointer exception please help me to resolve
#Component
public class AlertsToProfile extends Thread {
public final Map<Integer, List<String>> userMessages = Collections.synchronizedMap(new HashMap<Integer, List<String>>());
#Autowired
ProfileDAO profileDAO;
private String categoryType;
private String dataMessage;
public String getCategoryType() {
return categoryType;
}
public void setCategoryType(String categoryType) {
this.categoryType = categoryType;
}
public String getDataMessage() {
return dataMessage;
}
public void setDataMessage(String dataMessage) {
this.dataMessage = dataMessage;
}
public void run() {
String category=getCategoryType();
String data= getDataMessage();
List<Profile> all = profileDAO.findAll();
if (all != null) {
if (category == "All" || category.equalsIgnoreCase("All")) {
for (Profile profile : all) {
List<String> list = userMessages.get(profile.getId());
if (list == null ) {
ArrayList<String> strings = new ArrayList<String>();
strings.add(data);
userMessages.put(profile.getId(), strings);
} else {
list.add(data);
}
}
}
}
}
and my service method is as follows
#Service
public class NoteManager
{
#Autowired AlertsToProfile alertsToProfile;
public void addNote(String type, String message, String category) {
alertsToProfile.setCategoryType(category);
String data = type + "," + message;
alertsToProfile.setDataMessage(data);
alertsToProfile.start();
System.out.println("addNotes is done");
}
But when i call start() method am getting null pointer exception please help me. I am new to spring with thread concept
It pretty obvious: you instantiate your thread directly, as opposed to letting spring create AlertsToProfile and auto wire your instance.
To fix this, create a Runnable around your run() method and embed that into a method, something like this:
public void startThread() {
new Thread(new Runnable() {
#Override
public void run() {
// your code in here
}}).start();
}
you will want to bind the Thread instance to a field in AlertsToProfile in order to avoid leaks and stop the thread when you're done.