Mô hình dữ liệu của chúng tôi được tách thành các lược đồ trên hai cơ sở dữ liệu. Các lược đồ được sử dụng trong sự cô lập ngoại trừ một vài mối quan hệ đơn khóa nối giữa hai lược đồ. Không có giao dịch viết nào sẽ kéo dài cả hai cơ sở dữ liệu.Các đối tượng Hibernate từ nhiều Cơ sở dữ liệu
Tương tự như câu hỏi này Doing a join over 2 tables in different databases using Hibernate, chúng tôi muốn sử dụng Hibernate để xử lý việc tham gia các thực thể. Chúng ta không thể sử dụng giải pháp cơ sở dữ liệu (các khung nhìn liên kết trên DB2).
Chúng tôi đã thiết lập Hibernate với hai cấu hình cơ sở dữ liệu riêng biệt (Doctor and Patient), hoạt động hoàn hảo khi sử dụng DAO để truy cập rõ ràng một phiên cụ thể.
Chúng tôi muốn sử dụng Hibernate để tự động truy xuất thực thể khi chúng tôi gọi DoctorBO.getExam().getPatient()
Trường hợp kiểm tra chứa id trỏ đến bảng Bệnh nhân trên cơ sở dữ liệu khác.
Một cách tôi đã cố gắng làm điều này là sử dụng một loại người dùng tùy chỉnh:
public class DistributedUserType implements UserType, ParameterizedType
{
public static final String CLASS = "CLASS";
public static final String SESSION = "SESSION";
private Class<? extends DistributedEntity> returnedClass;
private String session;
/** {@inheritDoc} */
@Override
public int[] sqlTypes()
{
// The column will only be the id
return new int[] { java.sql.Types.BIGINT };
}
/** {@inheritDoc} */
@Override
public Class<? extends DistributedEntity> returnedClass()
{
// Set by typedef parameter
return returnedClass;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
if (x == y)
{
return true;
}
if ((x == null) || (y == null))
{
return false;
}
Long xId = ((DistributedEntity) x).getId();
Long yId = ((DistributedEntity) y).getId();
if (xId.equals(yId))
{
return true;
}
else
{
return false;
}
}
/** {@inheritDoc} */
@Override
public int hashCode(Object x) throws HibernateException
{
assert (x != null);
return x.hashCode();
}
/** {@inheritDoc} */
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException
{
Long id = rs.getLong(names[0]);
return HibernateUtils.getSession(session).get(returnedClass, id);
}
/** {@inheritDoc} */
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException
{
DistributedEntity de = (DistributedEntity) value;
st.setLong(index, de.getId());
}
/** {@inheritDoc} */
@Override
public Object deepCopy(Object value) throws HibernateException
{
return value;
}
/** {@inheritDoc} */
@Override
public boolean isMutable()
{
return false;
}
/** {@inheritDoc} */
@Override
public Serializable disassemble(Object value) throws HibernateException
{
return (Serializable) value;
}
/** {@inheritDoc} */
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException
{
return cached;
}
/** {@inheritDoc} */
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException
{
return original;
}
/** {@inheritDoc} */
@Override
public void setParameterValues(Properties parameters)
{
String clazz = (String) parameters.get(CLASS);
try
{
returnedClass = ReflectHelper.classForName(clazz);
}
catch (ClassNotFoundException e)
{
throw new IllegalArgumentException("Class: " + clazz + " is not a known class type.");
}
session = (String) parameters.get(SESSION);
}
}
Mà sau đó sẽ được sử dụng:
@TypeDef(name = "testUserType", typeClass = DistributedUserType.class, parameters = {
@Parameter(name = DistributedUserType.CLASS, value = PatientBO.CLASSNAME),
@Parameter(name = DistributedUserType.SESSION, value = HibernateUtils.PATIENT_SESS) })
@Type(type = "testUserType")
@Column(name = "PATIENT_ID")
private PatientBO patient;
Các loại người dùng hoạt động - các dữ liệu được nạp một cách chính xác chỉ với Id của trường tồn tại trong cơ sở dữ liệu. Tôi đã thử nghiệm các ví dụ rất đơn giản của doctor.getExam().getPatient()
và doctor.getExam().setPatient()
và cả hai dường như hoạt động tốt, tuy nhiên tôi nghĩ rằng đây là một hack khủng khiếp và tôi không có kiến thức đầy đủ về Hibernate để biết nếu điều này là an toàn để sử dụng.
Có cách nào tốt hơn để đạt được những gì chúng tôi muốn không? Là cách tôi đã mô tả ở đây đầy đủ, hoặc nó sẽ gây ra những khó khăn trong tương lai?
+1 cho giải pháp thú vị. – Firo