0

I have a table, and I want to change state field of mapped table from 1 to 0 when I press delete button. Here is the logic.

It is my mapped table

@Entity
@Table(name = "POSITION_ACCOUNT")
public class PositionAccount {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ID", columnDefinition = "NUMERIC(15, 0)",unique = true,nullable = false)
    private Long id;
    public Long getId() {
        return id;
    }

    @Column(name = "ACCT_NUMBER")
    private String accountNumber;
    public String getAccountNumber() {        return accountNumber;    }

    @Column(name = "ACCT_NAME")
    private String accountName;
    public String getAccountName() {
        return accountName;
    }

    @Column(name = "CURRENCY_CODE")
    private String currencyCode;
    public String getCurrencyCode() {
        return currencyCode;
    }

    @Column(name = "BALANCE")
    private BigDecimal balance = new BigDecimal("0");

    public BigDecimal getBalance() {
        return balance;
    }

    @Column(name = "ACCT_TYPE")
    private String accountType;
    public String getAccountType() { return accountType; }

    @Column(name = "STATE")
    private int state = 1;
    public int getState() {
        return state;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public void setCurrencyCode(String currencyCode) {
        this.currencyCode = currencyCode;
    }

    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }

    public void setState(int state) {
        this.state = state;
    }

    public void setAccountType(String accountType) { this.accountType = accountType; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        PositionAccount that = (PositionAccount) o;

        return !(id != null ? !id.equals(that.id) : that.id != null);

    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "PositionAccount{" +
                "id=" + id +
                ", accountNumber='" + accountNumber + '\'' +
                ", accountName='" + accountName + '\'' +
                ", currencyCode='" + currencyCode + '\'' +
                ", balance=" + balance +
                ", state=" + state +
                '}';
    }
}

Here is my @ActionMethod

@Inject
private LoroNostroService service;
@Inject
private LoroNostroModel model;
@ActionMethod(ACTION_DELETE_ACCOUNT)
public void deleteAccount() {
    PositionAccount account = tv_loro_nostro_accounts.getSelectionModel().getSelectedItem();

    DeleteAccount input = new DeleteAccount();
    input.setAccountId(account.getId());
    input.setType(account.getAccountType());
    input.setAccNum(account.getAccountNumber());
    input.setAccName(account.getAccountName());
    input.setCurrency(account.getCurrencyCode());
    input.setBalance(account.getBalance());
    input.setCurState(0);

    service.deleteAccount(input, context.getTaskView(), result -> {
        model.getAccounts().addAll(result.getAccount());
        tv_loro_nostro_accounts.getSelectionModel().selectFirst();
    });
}

where tv_loro_nostro_accounts is TableView from which I make a selection. DeleteAccount class is a class where I define all fields of my table with getters and setters. service.deleteAccount after some manipulations goes here:

@Path("deleteAccount")
@POST
public DeleteAccount deleteAccount(DeleteAccount model){
    try {
    model = operationService.execute(model,(result, userDetails) -> {

        PositionAccount a = new PositionAccount();
        a.setAccountType(result.getType());
        a.setAccountNumber(result.getAccNum());
        a.setAccountName(result.getAccName());
        a.setCurrencyCode(result.getCurrency());
        a.setState(0);
        service.deleteAccount(a);

        result.setState(OperationState.DONE);
        return result;
    });
    }catch (AdcException e) {
        logger.error("X: ", e);
        model.setState(OperationState.ERROR);
        model.setErrorText(e.getLocalizedMessage(model.getLocale()));
    } catch (Exception e) {
        logger.error("X: ", e);
        model.setState(OperationState.ERROR);
        model.setErrorText(e.getLocalizedMessage());
    }
    return model;
}

where service.deleteAccount is

public void deleteAccount(PositionAccount account){
        repository.deleteAccount(account);
    }

and repository.deleteAccount is

public void deleteAccount(PositionAccount account){
        em.merge(account);
        em.refresh(account);
    }

When I run above, I receive error

Entity not managed; nested exception is java.lang.IllaegalArgumentException: Entity not managed

Please hrlp to fix above.

rakamakafo
  • 1,044
  • 2
  • 20
  • 39
  • You create in `deleteAccount(...)` a new object. If im not wrong, you need to persist the object first, so that it becomes managed. Not sure, but i think that merges is only suitable, if the object was in detached state. [See this for more valuebale information] (http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge) – lunatikz Jul 12 '15 at 13:27

1 Answers1

1

merge returnes the managed entity instance, so to make this not to throw exception do:

account = em.merge(account);
em.refresh(account);

However, refresh will overwrite all the changes, so it is not needed here. Your method should look like:

public void deleteAccount(PositionAccount account) {
        em.merge(account);
}
Dragan Bozanovic
  • 21,631
  • 4
  • 36
  • 100