On a project now where EJB3 was used. Big time problematic. Firstly, they are using JPA1 (open JPA) and do ZERO configuration. Same way it was used at another large bank. They have no understanding of their application profile and caching needs.
Secondly, and just as scary, the prior programmers were on this job for several years and used EntityManager.merge in their code; but, the objects they are merging are only partially populated. They are trying to load data from a web page into a database but end up zeroing out any attributes which do not have a corresponding Element on the web page form. Basically, a huge risk with EJB3 Entity beans is they do not work intuitively the way the average programmer thinks they do. So, this code has been around for at least a year without them ever realizing it doesn't work correctly. Amazing. And scary.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Consider this bug.
java.lang.NullPointerException
at com.bigoldbank.sig.fio.entity.bean.MoneyFund.getMinTxnAmount(MoneyFund.java:368)
and where this occurs in the code:
public double getMinTxnAmount() {
return this.minTxnAmount;
}
Here's the class prolog:
@Entity
@NamedQueries({
@NamedQuery(name = MoneyFund.findByAll, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName "),
@NamedQuery(name = MoneyFund.findByInternalCUSIP, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.internalCUSIP = :internalCUSIP and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByAllActive, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.activeFlag = 'Y' and (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName"),
@NamedQuery(name = MoneyFund.findByFamilyAndProspectus, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.familyName = :familyName and (ab.url IS NULL or ab.url = :url ) and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByProspectus, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.url = :url and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByFamily, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.familyName = :familyName and (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName")
})
public class MoneyFund implements Serializable {
…
The bug was not the object itself having null but one of Double versus double. That's just bad design to write code like this:
…
private Double minTxnAmount;
…
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
On a project now where EJB3 was used. Big time problematic. Firstly, they are using JPA1 (open JPA) and do ZERO configuration. Same way it was used at another large bank. They have no understanding of their application profile and caching needs.
Secondly, and just as scary, the prior programmers were on this job for several years and used EntityManager.merge in their code; but, the objects they are merging are only partially populated. They are trying to load data from a web page into a database but end up zeroing out any attributes which do not have a corresponding Element on the web page form. Basically, a huge risk with EJB3 Entity beans is they do not work intuitively the way the average programmer thinks they do. So, this code has been around for at least a year without them ever realizing it doesn't work correctly. Amazing. And scary.
Consider this bug.
java.lang.NullPointerException
at com.bigoldbank.sig.fio.entity.bean.MoneyFund.getMinTxnAmount(MoneyFund.java:368)
and where this occurs in the code:
public double getMinTxnAmount() {
return this.minTxnAmount;
}
Here's the class prolog:
@Entity
@NamedQueries({
@NamedQuery(name = MoneyFund.findByAll, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName "),
@NamedQuery(name = MoneyFund.findByInternalCUSIP, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.internalCUSIP = :internalCUSIP and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByAllActive, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.activeFlag = 'Y' and (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName"),
@NamedQuery(name = MoneyFund.findByFamilyAndProspectus, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.familyName = :familyName and (ab.url IS NULL or ab.url = :url ) and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByProspectus, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.url = :url and (ab.disableFund IS NULL or ab.disableFund <> 'Y')"),
@NamedQuery(name = MoneyFund.findByFamily, query = "SELECT OBJECT(ab) FROM MoneyFund AS ab WHERE ab.familyName = :familyName and (ab.disableFund IS NULL or ab.disableFund <> 'Y') order by ab.familyName, ab.fundName")
})
public class MoneyFund implements Serializable {
…
The bug was not the object itself having null but one of Double versus double. That's just bad design to write code like this:
…
private Double minTxnAmount;
…