After much searching and trials, I am stuck… I have two classes, one is ExpectedSecurityReturn and the other is ForecastReturnType. ForecastReturnType is a member of ExpectedSecurityReturn but should not be inserted when persisting data. I keep getting an “insufficient privileges” but I know that the user does have the delete/insert privileges to the table expected_security_return since I tested with JDBC and JPA delete works fine. Therefore, I think that it has to do with my classes.
@Table(name = "EXPECTED_SECURITY_RETURNS")
@Entity
@IdClass(ExpectedSecurityReturn.ExpectedSecurityReturnPK.class)
public class ExpectedSecurityReturn {
@Id
@Column(name = "REP_SEC_ID")
private Integer repSecId;
@Id
@Column(name = "AS_OF_DATE")
private Date date;
@Id
@ManyToOne(optional = false)
@JoinColumn(name = "RETURN_TYPE_ID", referencedColumnName = "RETURN_TYPE_ID", insertable=false)
private ForecastReturnType returnType;
@Column(name="CURR_TOUSD_RET") // local currency to usd
private Double currencyToUsdReturn;
}
The primary key class, which includes ForecastReturnType:
// ------------------------------
// PK
// ------------------------------
public static class ExpectedSecurityReturnPK implements Serializable {
private static final long serialVersionUID = 1325372032981567439L;
public ExpectedSecurityReturnPK() {
}
public ExpectedSecurityReturnPK(final Integer repSecId,
final Date asOfDate, ForecastReturnType returnType) {
if (repSecId == null)
throw new IllegalArgumentException("null rep sec id");
if (asOfDate == null)
throw new IllegalArgumentException("null asOfDate");
if (returnType == null)
throw new IllegalArgumentException("null returnType");
this.repSecId = repSecId;
this.date = new Date(asOfDate.getTime());
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final ExpectedSecurityReturnPK that = (ExpectedSecurityReturnPK) o;
if (repSecId != that.repSecId)
return false;
if (!date.equals(that.date))
return false;
if (!returnType.equals(that.returnType))
return false;
return true;
}
@Override
public int hashCode() {
int result = repSecId;
result = 31 * result + date.hashCode();
result = 31 * result + returnType.getForecastTypeId();
return result;
}
private int repSecId;
private Date date;
private ForecastReturnType returnType;
}
and ForecastReturnType:
@Table(name="EXPECTED_SEC_RET_TYPE_DECODE")
@Entity
public class ForecastReturnType {
@Id
@Column(name="RETURN_TYPE_ID")
private int forecastTypeId;
@Column(name="SHORT_NAME")
private String shortName;
@Column(name="LONG_NAME")
private String longName;
@OneToMany(fetch=FetchType.LAZY, mappedBy="returnType")
Collection<ExpectedSecurityReturn> expectedSecurityReturns;
}
Could anyone help me figure out what I am doing wrong? I tried many things without success… I think that the culprit is ExpectedSecurityReturn.returnType since I know that the user does not have privileges.
Basically, I need to insert/persist ExpectedSecurityReturn instances.
Well, there’s a couple of things.
I would heavily not recommend even trying to do this. You can waste away your life figuring out JPA annotations and weird issues like this that never quite seem to work right. You’ll also find that different JPA providers will behave slightly differently when it comes to more complex structures like this, and it goes doubly for inheritance.
You’re really much better off creating a unique key on EXPECTED_SECURITY_RETURNS, and just living with it, it will make your Java life much much easier.
If you have to do something like this, I’m not surprised that JPA is balking at having a primary key component be another entity object. Whilst this in of course quite possible in the RDBMS, it’s seemingly little things like this that will trip up JPA.
I would also check the query logs that your JPA impl will put out (it’s configurable fairly easily in the persistence definition for most JPA providers, certainly Ecpliselink and Hibernate). I’d be willing to bet it’s trying to run an update on EXPECTED_SEC_RET_TYPE_DECODE, and if not, it might be trying to obtain a lock (table, row or other depending on your DBMS). If the user doesn’t have permission to either execute a lock or an update on that table, depending on the exact implementation, the query could fail with a permissions problem.
It is reasonable for JPA to want to hold a lock on that table because there is a chance that during the transaction, the entry that is being referenced in EXPECTED_SEC_RET_TYPE_DECODE may get changed, so it must ensure that it doesn’t whilst updating/inserting on the other table. Last I checked, there is no way to tell JPA that this table is essentially static. If you’re using Hibernate, you might try the @ReadOnly annotation, but in the past, not much I’ve tried can get around things like this.
If you do find a better solution, feel free to post it so that the rest of us can learn!!